From 87b8aecea42fafb3d75dd943e6e3942e2a7133e7 Mon Sep 17 00:00:00 2001 From: gj Date: Wed, 15 Jan 1997 22:37:09 +0000 Subject: changes required in the gdb directory for making gdb using the sources in /usr/src/contrib/gdb. This is based on /usr/ports/devel/gdb. 2.2 candidate ? --- gnu/usr.bin/binutils/gdb/Makefile | 82 +- gnu/usr.bin/binutils/gdb/config.h | 91 + gnu/usr.bin/binutils/gdb/gdb.1 | 390 --- gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c | 802 ------ gnu/usr.bin/binutils/gdb/i386/kvm-fbsd.c | 941 +++++++ gnu/usr.bin/binutils/gdb/i386/nm.h | 146 +- gnu/usr.bin/binutils/gdb/i386/tm.h | 66 +- gnu/usr.bin/binutils/gdb/i386/version.c | 2 +- gnu/usr.bin/binutils/gdb/i386/xm.h | 8 +- gnu/usr.bin/binutils/gdb/kvm-fbsd.c | 941 +++++++ gnu/usr.bin/gdb/gdb/COPYING | 339 --- gnu/usr.bin/gdb/gdb/Makefile | 82 +- gnu/usr.bin/gdb/gdb/annotate.c | 521 ---- gnu/usr.bin/gdb/gdb/annotate.h | 95 - gnu/usr.bin/gdb/gdb/ansidecl.h | 141 - gnu/usr.bin/gdb/gdb/bfdlink.h | 411 --- gnu/usr.bin/gdb/gdb/blockframe.c | 866 ------ gnu/usr.bin/gdb/gdb/breakpoint.c | 4052 -------------------------- gnu/usr.bin/gdb/gdb/breakpoint.h | 419 --- gnu/usr.bin/gdb/gdb/buildsym.c | 964 ------- gnu/usr.bin/gdb/gdb/buildsym.h | 259 -- gnu/usr.bin/gdb/gdb/c-exp.y | 1601 ----------- gnu/usr.bin/gdb/gdb/c-lang.c | 469 ---- gnu/usr.bin/gdb/gdb/c-lang.h | 38 - gnu/usr.bin/gdb/gdb/c-typeprint.c | 795 ------ gnu/usr.bin/gdb/gdb/c-valprint.c | 513 ---- gnu/usr.bin/gdb/gdb/call-cmds.h | 28 - gnu/usr.bin/gdb/gdb/ch-exp.y | 1997 ------------- gnu/usr.bin/gdb/gdb/ch-lang.c | 355 --- gnu/usr.bin/gdb/gdb/ch-lang.h | 44 - gnu/usr.bin/gdb/gdb/ch-typeprint.c | 315 --- gnu/usr.bin/gdb/gdb/ch-valprint.c | 581 ---- gnu/usr.bin/gdb/gdb/coffread.c | 2101 -------------- gnu/usr.bin/gdb/gdb/command.c | 1331 --------- gnu/usr.bin/gdb/gdb/command.h | 246 -- gnu/usr.bin/gdb/gdb/compat_que.c | 63 - gnu/usr.bin/gdb/gdb/complaints.c | 158 -- gnu/usr.bin/gdb/gdb/complaints.h | 46 - gnu/usr.bin/gdb/gdb/config.h | 91 + gnu/usr.bin/gdb/gdb/copying.c | 327 --- gnu/usr.bin/gdb/gdb/core.c | 339 --- gnu/usr.bin/gdb/gdb/coredep.c | 124 - gnu/usr.bin/gdb/gdb/corelow.c | 333 --- gnu/usr.bin/gdb/gdb/cp-valprint.c | 512 ---- gnu/usr.bin/gdb/gdb/dbxread.c | 2462 ---------------- gnu/usr.bin/gdb/gdb/dcache.c | 236 -- gnu/usr.bin/gdb/gdb/dcache.h | 83 - gnu/usr.bin/gdb/gdb/defs.h | 947 ------- gnu/usr.bin/gdb/gdb/demangle.c | 181 -- gnu/usr.bin/gdb/gdb/demangle.h | 80 - gnu/usr.bin/gdb/gdb/dis-asm.h | 179 -- gnu/usr.bin/gdb/gdb/dis-buf.c | 70 - gnu/usr.bin/gdb/gdb/disassemble.c | 148 - gnu/usr.bin/gdb/gdb/dwarfread.c | 3876 ------------------------- gnu/usr.bin/gdb/gdb/elfread.c | 805 ------ gnu/usr.bin/gdb/gdb/environ.c | 194 -- gnu/usr.bin/gdb/gdb/environ.h | 58 - gnu/usr.bin/gdb/gdb/eval.c | 1226 -------- gnu/usr.bin/gdb/gdb/exec.c | 506 ---- gnu/usr.bin/gdb/gdb/expprint.c | 624 ----- gnu/usr.bin/gdb/gdb/expression.h | 316 --- gnu/usr.bin/gdb/gdb/findvar.c | 1242 -------- gnu/usr.bin/gdb/gdb/floatformat.h | 87 - gnu/usr.bin/gdb/gdb/fopen-bin.h | 27 - gnu/usr.bin/gdb/gdb/fopen-same.h | 27 - gnu/usr.bin/gdb/gdb/fork-child.c | 300 -- gnu/usr.bin/gdb/gdb/frame.h | 240 -- gnu/usr.bin/gdb/gdb/freebsd-nat.c | 802 ------ gnu/usr.bin/gdb/gdb/gdb-stabs.h | 76 - gnu/usr.bin/gdb/gdb/gdb.1 | 390 --- gnu/usr.bin/gdb/gdb/gdbcmd.h | 101 - gnu/usr.bin/gdb/gdb/gdbcore.h | 139 - gnu/usr.bin/gdb/gdb/gdbm.h | 91 - gnu/usr.bin/gdb/gdb/gdbtypes.c | 1581 ----------- gnu/usr.bin/gdb/gdb/gdbtypes.h | 735 ----- gnu/usr.bin/gdb/gdb/getopt.h | 129 - gnu/usr.bin/gdb/gdb/i386-dis.c | 1959 ------------- gnu/usr.bin/gdb/gdb/i386-pinsn.c | 37 - gnu/usr.bin/gdb/gdb/i386-tdep.c | 668 ----- gnu/usr.bin/gdb/gdb/i386freebsd.h | 23 + gnu/usr.bin/gdb/gdb/ieee.h | 132 - gnu/usr.bin/gdb/gdb/infcmd.c | 1384 --------- gnu/usr.bin/gdb/gdb/inferior.h | 420 --- gnu/usr.bin/gdb/gdb/inflow.c | 711 ----- gnu/usr.bin/gdb/gdb/infptrace.c | 507 ---- gnu/usr.bin/gdb/gdb/infrun.c | 2037 -------------- gnu/usr.bin/gdb/gdb/inftarg.c | 328 --- gnu/usr.bin/gdb/gdb/init.c | 17 +- gnu/usr.bin/gdb/gdb/kcorelow.c | 21 +- gnu/usr.bin/gdb/gdb/kvm-fbsd.c | 941 +++++++ gnu/usr.bin/gdb/gdb/language.c | 1311 --------- gnu/usr.bin/gdb/gdb/language.h | 413 --- gnu/usr.bin/gdb/gdb/libiberty.h | 107 - gnu/usr.bin/gdb/gdb/m2-exp.y | 1169 -------- gnu/usr.bin/gdb/gdb/m2-lang.c | 447 --- gnu/usr.bin/gdb/gdb/m2-lang.h | 31 - gnu/usr.bin/gdb/gdb/m2-typeprint.c | 49 - gnu/usr.bin/gdb/gdb/m2-valprint.c | 45 - gnu/usr.bin/gdb/gdb/main.c | 571 ---- gnu/usr.bin/gdb/gdb/maint.c | 295 -- gnu/usr.bin/gdb/gdb/mdebugread.c | 4053 --------------------------- gnu/usr.bin/gdb/gdb/mem-break.c | 104 - gnu/usr.bin/gdb/gdb/minsyms.c | 648 ----- gnu/usr.bin/gdb/gdb/mipsread.c | 457 --- gnu/usr.bin/gdb/gdb/nlmread.c | 308 -- gnu/usr.bin/gdb/gdb/nm.h | 146 +- gnu/usr.bin/gdb/gdb/objfiles.c | 868 ------ gnu/usr.bin/gdb/gdb/objfiles.h | 451 --- gnu/usr.bin/gdb/gdb/obstack.h | 513 ---- gnu/usr.bin/gdb/gdb/parse.c | 890 ------ gnu/usr.bin/gdb/gdb/parser-defs.h | 186 -- gnu/usr.bin/gdb/gdb/partial-stab.h | 679 ----- gnu/usr.bin/gdb/gdb/printcmd.c | 2220 --------------- gnu/usr.bin/gdb/gdb/remote-utils.c | 704 ----- gnu/usr.bin/gdb/gdb/remote-utils.h | 142 - gnu/usr.bin/gdb/gdb/remote.c | 1470 ---------- gnu/usr.bin/gdb/gdb/ser-unix.c | 684 ----- gnu/usr.bin/gdb/gdb/serial.c | 265 -- gnu/usr.bin/gdb/gdb/serial.h | 158 -- gnu/usr.bin/gdb/gdb/signals.h | 27 - gnu/usr.bin/gdb/gdb/solib.c | 1549 ---------- gnu/usr.bin/gdb/gdb/solib.h | 56 - gnu/usr.bin/gdb/gdb/source.c | 1415 ---------- gnu/usr.bin/gdb/gdb/stabsread.c | 3948 -------------------------- gnu/usr.bin/gdb/gdb/stabsread.h | 212 -- gnu/usr.bin/gdb/gdb/stack.c | 1482 ---------- gnu/usr.bin/gdb/gdb/symfile.c | 1684 ----------- gnu/usr.bin/gdb/gdb/symfile.h | 250 -- gnu/usr.bin/gdb/gdb/symmisc.c | 988 ------- gnu/usr.bin/gdb/gdb/symtab.c | 3251 --------------------- gnu/usr.bin/gdb/gdb/symtab.h | 1176 -------- gnu/usr.bin/gdb/gdb/target.c | 1316 --------- gnu/usr.bin/gdb/gdb/target.h | 649 ----- gnu/usr.bin/gdb/gdb/terminal.h | 62 - gnu/usr.bin/gdb/gdb/thread.c | 371 --- gnu/usr.bin/gdb/gdb/thread.h | 36 - gnu/usr.bin/gdb/gdb/tm-i386v.h | 296 -- gnu/usr.bin/gdb/gdb/tm.h | 66 +- gnu/usr.bin/gdb/gdb/top.c | 2494 ---------------- gnu/usr.bin/gdb/gdb/top.h | 48 - gnu/usr.bin/gdb/gdb/typeprint.c | 297 -- gnu/usr.bin/gdb/gdb/typeprint.h | 21 - gnu/usr.bin/gdb/gdb/utils.c | 1790 ------------ gnu/usr.bin/gdb/gdb/valarith.c | 1068 ------- gnu/usr.bin/gdb/gdb/valops.c | 1898 ------------- gnu/usr.bin/gdb/gdb/valprint.c | 1087 ------- gnu/usr.bin/gdb/gdb/valprint.h | 44 - gnu/usr.bin/gdb/gdb/value.h | 482 ---- gnu/usr.bin/gdb/gdb/values.c | 1508 ---------- gnu/usr.bin/gdb/gdb/version.c | 2 +- gnu/usr.bin/gdb/gdb/wait.h | 38 - gnu/usr.bin/gdb/gdb/xm.h | 8 +- 152 files changed, 3320 insertions(+), 96851 deletions(-) create mode 100644 gnu/usr.bin/binutils/gdb/config.h delete mode 100644 gnu/usr.bin/binutils/gdb/gdb.1 delete mode 100644 gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c create mode 100644 gnu/usr.bin/binutils/gdb/i386/kvm-fbsd.c create mode 100644 gnu/usr.bin/binutils/gdb/kvm-fbsd.c delete mode 100644 gnu/usr.bin/gdb/gdb/COPYING delete mode 100644 gnu/usr.bin/gdb/gdb/annotate.c delete mode 100644 gnu/usr.bin/gdb/gdb/annotate.h delete mode 100644 gnu/usr.bin/gdb/gdb/ansidecl.h delete mode 100644 gnu/usr.bin/gdb/gdb/bfdlink.h delete mode 100644 gnu/usr.bin/gdb/gdb/blockframe.c delete mode 100644 gnu/usr.bin/gdb/gdb/breakpoint.c delete mode 100644 gnu/usr.bin/gdb/gdb/breakpoint.h delete mode 100644 gnu/usr.bin/gdb/gdb/buildsym.c delete mode 100644 gnu/usr.bin/gdb/gdb/buildsym.h delete mode 100644 gnu/usr.bin/gdb/gdb/c-exp.y delete mode 100644 gnu/usr.bin/gdb/gdb/c-lang.c delete mode 100644 gnu/usr.bin/gdb/gdb/c-lang.h delete mode 100644 gnu/usr.bin/gdb/gdb/c-typeprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/c-valprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/call-cmds.h delete mode 100644 gnu/usr.bin/gdb/gdb/ch-exp.y delete mode 100644 gnu/usr.bin/gdb/gdb/ch-lang.c delete mode 100644 gnu/usr.bin/gdb/gdb/ch-lang.h delete mode 100644 gnu/usr.bin/gdb/gdb/ch-typeprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/ch-valprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/coffread.c delete mode 100644 gnu/usr.bin/gdb/gdb/command.c delete mode 100644 gnu/usr.bin/gdb/gdb/command.h delete mode 100644 gnu/usr.bin/gdb/gdb/compat_que.c delete mode 100644 gnu/usr.bin/gdb/gdb/complaints.c delete mode 100644 gnu/usr.bin/gdb/gdb/complaints.h create mode 100644 gnu/usr.bin/gdb/gdb/config.h delete mode 100644 gnu/usr.bin/gdb/gdb/copying.c delete mode 100644 gnu/usr.bin/gdb/gdb/core.c delete mode 100644 gnu/usr.bin/gdb/gdb/coredep.c delete mode 100644 gnu/usr.bin/gdb/gdb/corelow.c delete mode 100644 gnu/usr.bin/gdb/gdb/cp-valprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/dbxread.c delete mode 100644 gnu/usr.bin/gdb/gdb/dcache.c delete mode 100644 gnu/usr.bin/gdb/gdb/dcache.h delete mode 100644 gnu/usr.bin/gdb/gdb/defs.h delete mode 100644 gnu/usr.bin/gdb/gdb/demangle.c delete mode 100644 gnu/usr.bin/gdb/gdb/demangle.h delete mode 100644 gnu/usr.bin/gdb/gdb/dis-asm.h delete mode 100644 gnu/usr.bin/gdb/gdb/dis-buf.c delete mode 100644 gnu/usr.bin/gdb/gdb/disassemble.c delete mode 100644 gnu/usr.bin/gdb/gdb/dwarfread.c delete mode 100644 gnu/usr.bin/gdb/gdb/elfread.c delete mode 100644 gnu/usr.bin/gdb/gdb/environ.c delete mode 100644 gnu/usr.bin/gdb/gdb/environ.h delete mode 100644 gnu/usr.bin/gdb/gdb/eval.c delete mode 100644 gnu/usr.bin/gdb/gdb/exec.c delete mode 100644 gnu/usr.bin/gdb/gdb/expprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/expression.h delete mode 100644 gnu/usr.bin/gdb/gdb/findvar.c delete mode 100644 gnu/usr.bin/gdb/gdb/floatformat.h delete mode 100644 gnu/usr.bin/gdb/gdb/fopen-bin.h delete mode 100644 gnu/usr.bin/gdb/gdb/fopen-same.h delete mode 100644 gnu/usr.bin/gdb/gdb/fork-child.c delete mode 100644 gnu/usr.bin/gdb/gdb/frame.h delete mode 100644 gnu/usr.bin/gdb/gdb/freebsd-nat.c delete mode 100644 gnu/usr.bin/gdb/gdb/gdb-stabs.h delete mode 100644 gnu/usr.bin/gdb/gdb/gdb.1 delete mode 100644 gnu/usr.bin/gdb/gdb/gdbcmd.h delete mode 100644 gnu/usr.bin/gdb/gdb/gdbcore.h delete mode 100644 gnu/usr.bin/gdb/gdb/gdbm.h delete mode 100644 gnu/usr.bin/gdb/gdb/gdbtypes.c delete mode 100644 gnu/usr.bin/gdb/gdb/gdbtypes.h delete mode 100644 gnu/usr.bin/gdb/gdb/getopt.h delete mode 100644 gnu/usr.bin/gdb/gdb/i386-dis.c delete mode 100644 gnu/usr.bin/gdb/gdb/i386-pinsn.c delete mode 100644 gnu/usr.bin/gdb/gdb/i386-tdep.c create mode 100644 gnu/usr.bin/gdb/gdb/i386freebsd.h delete mode 100644 gnu/usr.bin/gdb/gdb/ieee.h delete mode 100644 gnu/usr.bin/gdb/gdb/infcmd.c delete mode 100644 gnu/usr.bin/gdb/gdb/inferior.h delete mode 100644 gnu/usr.bin/gdb/gdb/inflow.c delete mode 100644 gnu/usr.bin/gdb/gdb/infptrace.c delete mode 100644 gnu/usr.bin/gdb/gdb/infrun.c delete mode 100644 gnu/usr.bin/gdb/gdb/inftarg.c create mode 100644 gnu/usr.bin/gdb/gdb/kvm-fbsd.c delete mode 100644 gnu/usr.bin/gdb/gdb/language.c delete mode 100644 gnu/usr.bin/gdb/gdb/language.h delete mode 100644 gnu/usr.bin/gdb/gdb/libiberty.h delete mode 100644 gnu/usr.bin/gdb/gdb/m2-exp.y delete mode 100644 gnu/usr.bin/gdb/gdb/m2-lang.c delete mode 100644 gnu/usr.bin/gdb/gdb/m2-lang.h delete mode 100644 gnu/usr.bin/gdb/gdb/m2-typeprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/m2-valprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/main.c delete mode 100644 gnu/usr.bin/gdb/gdb/maint.c delete mode 100644 gnu/usr.bin/gdb/gdb/mdebugread.c delete mode 100644 gnu/usr.bin/gdb/gdb/mem-break.c delete mode 100644 gnu/usr.bin/gdb/gdb/minsyms.c delete mode 100644 gnu/usr.bin/gdb/gdb/mipsread.c delete mode 100644 gnu/usr.bin/gdb/gdb/nlmread.c delete mode 100644 gnu/usr.bin/gdb/gdb/objfiles.c delete mode 100644 gnu/usr.bin/gdb/gdb/objfiles.h delete mode 100644 gnu/usr.bin/gdb/gdb/obstack.h delete mode 100644 gnu/usr.bin/gdb/gdb/parse.c delete mode 100644 gnu/usr.bin/gdb/gdb/parser-defs.h delete mode 100644 gnu/usr.bin/gdb/gdb/partial-stab.h delete mode 100644 gnu/usr.bin/gdb/gdb/printcmd.c delete mode 100644 gnu/usr.bin/gdb/gdb/remote-utils.c delete mode 100644 gnu/usr.bin/gdb/gdb/remote-utils.h delete mode 100644 gnu/usr.bin/gdb/gdb/remote.c delete mode 100644 gnu/usr.bin/gdb/gdb/ser-unix.c delete mode 100644 gnu/usr.bin/gdb/gdb/serial.c delete mode 100644 gnu/usr.bin/gdb/gdb/serial.h delete mode 100644 gnu/usr.bin/gdb/gdb/signals.h delete mode 100644 gnu/usr.bin/gdb/gdb/solib.c delete mode 100644 gnu/usr.bin/gdb/gdb/solib.h delete mode 100644 gnu/usr.bin/gdb/gdb/source.c delete mode 100644 gnu/usr.bin/gdb/gdb/stabsread.c delete mode 100644 gnu/usr.bin/gdb/gdb/stabsread.h delete mode 100644 gnu/usr.bin/gdb/gdb/stack.c delete mode 100644 gnu/usr.bin/gdb/gdb/symfile.c delete mode 100644 gnu/usr.bin/gdb/gdb/symfile.h delete mode 100644 gnu/usr.bin/gdb/gdb/symmisc.c delete mode 100644 gnu/usr.bin/gdb/gdb/symtab.c delete mode 100644 gnu/usr.bin/gdb/gdb/symtab.h delete mode 100644 gnu/usr.bin/gdb/gdb/target.c delete mode 100644 gnu/usr.bin/gdb/gdb/target.h delete mode 100644 gnu/usr.bin/gdb/gdb/terminal.h delete mode 100644 gnu/usr.bin/gdb/gdb/thread.c delete mode 100644 gnu/usr.bin/gdb/gdb/thread.h delete mode 100644 gnu/usr.bin/gdb/gdb/tm-i386v.h delete mode 100644 gnu/usr.bin/gdb/gdb/top.c delete mode 100644 gnu/usr.bin/gdb/gdb/top.h delete mode 100644 gnu/usr.bin/gdb/gdb/typeprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/typeprint.h delete mode 100644 gnu/usr.bin/gdb/gdb/utils.c delete mode 100644 gnu/usr.bin/gdb/gdb/valarith.c delete mode 100644 gnu/usr.bin/gdb/gdb/valops.c delete mode 100644 gnu/usr.bin/gdb/gdb/valprint.c delete mode 100644 gnu/usr.bin/gdb/gdb/valprint.h delete mode 100644 gnu/usr.bin/gdb/gdb/value.h delete mode 100644 gnu/usr.bin/gdb/gdb/values.c delete mode 100644 gnu/usr.bin/gdb/gdb/wait.h (limited to 'gnu/usr.bin') diff --git a/gnu/usr.bin/binutils/gdb/Makefile b/gnu/usr.bin/binutils/gdb/Makefile index 47ad0db..981ac45 100644 --- a/gnu/usr.bin/binutils/gdb/Makefile +++ b/gnu/usr.bin/binutils/gdb/Makefile @@ -1,16 +1,20 @@ # $FreeBSD$ PROG = gdb + +GDBDIR= ${.CURDIR}/../../../../contrib/gdb +.PATH: ${GDBDIR}/gdb +.PATH: ${GDBDIR}/opcodes + BINDIR= /usr/bin -CLEANFILES+= y.tab.h c-exp.tab.c ch-exp.tab.c m2-exp.tab.c SRCS = annotate.c blockframe.c breakpoint.c buildsym.c c-lang.c \ c-typeprint.c c-valprint.c ch-lang.c ch-typeprint.c \ - ch-valprint.c coffread.c command.c complaints.c copying.c core.c \ - coredep.c corelow.c cp-valprint.c \ - dcache.c dbxread.c demangle.c disassemble.c dis-buf.c dwarfread.c \ + ch-valprint.c coffread.c command.c complaints.c copying.c core-aout.c \ + corelow.c cp-valprint.c \ + dcache.c dbxread.c demangle.c dwarfread.c \ elfread.c environ.c eval.c exec.c expprint.c \ - findvar.c fork-child.c freebsd-nat.c gdbtypes.c i386-dis.c \ - i386-pinsn.c i386-tdep.c infcmd.c inflow.c infptrace.c \ + findvar.c fork-child.c i386b-nat.c gdbtypes.c \ + i386-tdep.c infcmd.c inflow.c infptrace.c \ infrun.c inftarg.c init.c kcorelow.c language.c \ m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \ mem-break.c minsyms.c objfiles.c parse.c \ @@ -19,36 +23,29 @@ SRCS = annotate.c blockframe.c breakpoint.c buildsym.c c-lang.c \ symtab.c target.c thread.c top.c \ typeprint.c utils.c valarith.c valops.c \ valprint.c values.c version.c serial.c ser-unix.c mdebugread.c\ - c-exp.tab.c ch-exp.tab.c m2-exp.tab.c compat_que.c - -c-exp.tab.c: $(.CURDIR)/c-exp.y - yacc -d -p c_ $(.CURDIR)/c-exp.y - sed -e '/extern.*malloc/d' -e '/extern.*realloc/d' -e '/extern.*free/d' \ - -e '/include.*malloc.h/d' -e 's/malloc/xmalloc/g' \ - -e 's/realloc/xrealloc/g' < y.tab.c > c-exp.new - rm -f y.tab.c - mv -f c-exp.new ./c-exp.tab.c + c-exp.tab.c f-exp.tab.c m2-exp.tab.c i387-tdep.c \ + kvm-fbsd.c bcache.c \ + corefile.c ch-exp.c f-lang.c scm-exp.c scm-lang.c \ + scm-valprint.c f-typeprint.c f-valprint.c nlmread.c \ + callback.c +SRCS+= i386-dis.c dis-buf.c disassemble.c -ch-exp.tab.c: $(.CURDIR)/ch-exp.y - yacc -d -p ch_ $(.CURDIR)/ch-exp.y - sed -e '/extern.*malloc/d' -e '/extern.*realloc/d' -e '/extern.*free/d' \ - -e '/include.*malloc.h/d' -e 's/malloc/xmalloc/g' \ - -e 's/realloc/xrealloc/g' < y.tab.c > ch-exp.new - rm -f y.tab.c - mv -f ch-exp.new ./ch-exp.tab.c - -m2-exp.tab.c: $(.CURDIR)/m2-exp.y - yacc -d -p m2_ $(.CURDIR)/m2-exp.y - sed -e '/extern.*malloc/d' -e '/extern.*realloc/d' -e '/extern.*free/d' \ - -e '/include.*malloc.h/d' -e 's/malloc/xmalloc/g' \ - -e 's/realloc/xrealloc/g' < y.tab.c > m2-exp.new - rm -f y.tab.c - mv -f m2-exp.new ./m2-exp.tab.c +CFLAGS+= -I$(.CURDIR) -I${DESTDIR}/usr/include/readline -I$(.CURDIR)/../bfd +# use phkmalloc +CFLAGS+= -DNO_MMALLOC +# uncomment the next line if you want to debug gdb +#CFLAGS+= -g +.if exists(${.OBJDIR}/../bfd) +LDADD+= -L${.OBJDIR}/../bfd -lbfd +DPADD+= ${.OBJDIR}/../bfd/libbfd.a +.else +LDADD+= -L${.CURDIR}/../bfd/ -lbfd +DPADD+= ${.CURDIR}/../bfd/libbfd.a +.endif -CFLAGS+= -I$(.CURDIR)/. -I${DESTDIR}/usr/include/readline -I$(.CURDIR)/../bfd -DPADD+= ${LIBREADLINE} ${LIBTERMCAP} ${LIBGNUREGEX} -LDADD+= -lreadline -ltermcap -lgnuregex +DPADD+= ${LIBREADLINE} ${LIBGNUREGEX} +LDADD+= -lreadline -lgnuregex .if exists(${.OBJDIR}/../libiberty) LDADD+= -L${.OBJDIR}/../libiberty -liberty @@ -58,20 +55,15 @@ LDADD+= -L${.CURDIR}/../libiberty/ -liberty DPADD+= ${.CURDIR}/../libiberty/libiberty.a .endif -.if exists(${.OBJDIR}/../bfd) -LDADD+= -L${.OBJDIR}/../bfd -lbfd -DPADD+= ${.OBJDIR}/../bfd/libbfd.a -.else -LDADD+= -L${.CURDIR}/../bfd/ -lbfd -DPADD+= ${.CURDIR}/../bfd/libbfd.a -.endif +DPADD+= ${LIBTERMCAP} +LDADD+= -ltermcap -lmalloc -.if exists(${.OBJDIR}/../mmalloc) -LDADD+= -L${.OBJDIR}/../mmalloc -lmmalloc -DPADD+= ${.OBJDIR}/../mmalloc/libmmalloc.a +.if exists(${.OBJDIR}/../libiberty) +LDADD+= -L${.OBJDIR}/../libiberty -liberty +DPADD+= ${.OBJDIR}/../libiberty/libiberty.a .else -LDADD+= -L${.CURDIR}/../mmalloc/ -lmmalloc -DPADD+= ${.CURDIR}/../mmalloc/libmmalloc.a +LDADD+= -L${.CURDIR}/../libiberty/ -liberty +DPADD+= ${.CURDIR}/../libiberty/libiberty.a .endif .include diff --git a/gnu/usr.bin/binutils/gdb/config.h b/gnu/usr.bin/binutils/gdb/config.h new file mode 100644 index 0000000..29f0a3c --- /dev/null +++ b/gnu/usr.bin/binutils/gdb/config.h @@ -0,0 +1,91 @@ +/* config.h. Generated automatically by configure. */ +/* config.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define if the `long double' type works. */ +#define HAVE_LONG_DOUBLE 1 + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define if on MINIX. */ +/* #undef _MINIX */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if fpregset_t type is available. */ +/* #undef HAVE_FPREGSET_T */ + +/* Define if gregset_t type is available. */ +/* #undef HAVE_GREGSET_T */ + +/* Define if the "%Lg" format works to print long doubles. */ +#define PRINTF_HAS_LONG_DOUBLE 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the sbrk function. */ +#define HAVE_SBRK 1 + +/* Define if you have the setpgid function. */ +#define HAVE_SETPGID 1 + +/* Define if you have the valloc function. */ +#define HAVE_VALLOC 1 + +/* Define if you have the header file. */ +/* #undef HAVE_ENDIAN_H */ + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINK_H 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +#define HAVE_SGTTY_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PROCFS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_TERMIO_H */ + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the dl library (-ldl). */ +/* #undef HAVE_LIBDL */ diff --git a/gnu/usr.bin/binutils/gdb/gdb.1 b/gnu/usr.bin/binutils/gdb/gdb.1 deleted file mode 100644 index 13a6a77..0000000 --- a/gnu/usr.bin/binutils/gdb/gdb.1 +++ /dev/null @@ -1,390 +0,0 @@ -.\" Copyright (c) 1991 Free Software Foundation -.\" See section COPYING for conditions for redistribution -.\" $FreeBSD$ -.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools" -.SH NAME -gdb \- The GNU Debugger -.SH SYNOPSIS -.na -.TP -.B gdb -.RB "[\|" \-help "\|]" -.RB "[\|" \-nx "\|]" -.RB "[\|" \-q "\|]" -.RB "[\|" \-k "\|]" -.RB "[\|" \-w "\|]" -.RB "[\|" \-batch "\|]" -.RB "[\|" \-cd=\c -.I dir\c -\|] -.RB "[\|" \-f "\|]" -.RB "[\|" "\-b\ "\c -.IR bps "\|]" -.RB "[\|" "\-tty="\c -.IR dev "\|]" -.RB "[\|" "\-s "\c -.I symfile\c -\&\|] -.RB "[\|" "\-e "\c -.I prog\c -\&\|] -.RB "[\|" "\-se "\c -.I prog\c -\&\|] -.RB "[\|" "\-c "\c -.I core\c -\&\|] -.RB "[\|" "\-x "\c -.I cmds\c -\&\|] -.RB "[\|" "\-d "\c -.I dir\c -\&\|] -.RB "[\|" \c -.I prog\c -.RB "[\|" \c -.IR core \||\| procID\c -\&\|]\&\|] -.ad b -.SH DESCRIPTION -The purpose of a debugger such as GDB is to allow you to see what is -going on ``inside'' another program while it executes\(em\&or what another -program was doing at the moment it crashed. - -GDB can do four main kinds of things (plus other things in support of -these) to help you catch bugs in the act: - -.TP -\ \ \ \(bu -Start your program, specifying anything that might affect its behavior. - -.TP -\ \ \ \(bu -Make your program stop on specified conditions. - -.TP -\ \ \ \(bu -Examine what has happened, when your program has stopped. - -.TP -\ \ \ \(bu -Change things in your program, so you can experiment with correcting the -effects of one bug and go on to learn about another. -.PP - -You can use GDB to debug programs written in C, C++, and Modula-2. -Fortran support will be added when a GNU Fortran compiler is ready. - -GDB is invoked with the shell command \c -.B gdb\c -\&. Once started, it reads -commands from the terminal until you tell it to exit with the GDB -command \c -.B quit\c -\&. You can get online help from \c -.B gdb\c -\& itself -by using the command \c -.B help\c -\&. - -You can run \c -.B gdb\c -\& with no arguments or options; but the most -usual way to start GDB is with one argument or two, specifying an -executable program as the argument: -.sp -.br -gdb\ program -.br -.sp - -You can also start with both an executable program and a core file specified: -.sp -.br -gdb\ program\ core -.br -.sp - -You can, instead, specify a process ID as a second argument, if you want -to debug a running process: -.sp -.br -gdb\ program\ 1234 -.br -.sp - -would attach GDB to process \c -.B 1234\c -\& (unless you also have a file -named `\|\c -.B 1234\c -\&\|'; GDB does check for a core file first). - -Here are some of the most frequently needed GDB commands: -.TP -.B break \fR[\|\fIfile\fB:\fR\|]\fIfunction -\& -Set a breakpoint at \c -.I function\c -\& (in \c -.I file\c -\&). -.TP -.B run \fR[\|\fIarglist\fR\|] -Start your program (with \c -.I arglist\c -\&, if specified). -.TP -.B bt -Backtrace: display the program stack. -.TP -.BI print " expr"\c -\& -Display the value of an expression. -.TP -.B c -Continue running your program (after stopping, e.g. at a breakpoint). -.TP -.B next -Execute next program line (after stopping); step \c -.I over\c -\& any -function calls in the line. -.TP -.B step -Execute next program line (after stopping); step \c -.I into\c -\& any -function calls in the line. -.TP -.B help \fR[\|\fIname\fR\|] -Show information about GDB command \c -.I name\c -\&, or general information -about using GDB. -.TP -.B quit -Exit from GDB. -.PP -For full details on GDB, see \c -.I -Using GDB: A Guide to the GNU Source-Level Debugger\c -\&, by Richard M. Stallman and Roland H. Pesch. The same text is available online -as the \c -.B gdb\c -\& entry in the \c -.B info\c -\& program. -.SH OPTIONS -Any arguments other than options specify an executable -file and core file (or process ID); that is, the first argument -encountered with no -associated option flag is equivalent to a `\|\c -.B \-se\c -\&\|' option, and the -second, if any, is equivalent to a `\|\c -.B \-c\c -\&\|' option if it's the name of a file. Many options have -both long and short forms; both are shown here. The long forms are also -recognized if you truncate them, so long as enough of the option is -present to be unambiguous. (If you prefer, you can flag option -arguments with `\|\c -.B +\c -\&\|' rather than `\|\c -.B \-\c -\&\|', though we illustrate the -more usual convention.) - -All the options and command line arguments you give are processed -in sequential order. The order makes a difference when the -`\|\c -.B \-x\c -\&\|' option is used. - -.TP -.B \-help -.TP -.B \-h -List all options, with brief explanations. - -.TP -.BI "\-symbols=" "file"\c -.TP -.BI "\-s " "file"\c -\& -Read symbol table from file \c -.I file\c -\&. - -.TP -.BI "\-exec=" "file"\c -.TP -.BI "\-e " "file"\c -\& -Use file \c -.I file\c -\& as the executable file to execute when -appropriate, and for examining pure data in conjunction with a core -dump. - -.TP -.BI "\-se=" "file"\c -\& -Read symbol table from file \c -.I file\c -\& and use it as the executable -file. - -.TP -.BI "\-core=" "file"\c -.TP -.BI "\-c " "file"\c -\& -Use file \c -.I file\c -\& as a core dump to examine. - -.TP -.BI "\-command=" "file"\c -.TP -.BI "\-x " "file"\c -\& -Execute GDB commands from file \c -.I file\c -\&. - -.TP -.BI "\-directory=" "directory"\c -.TP -.BI "\-d " "directory"\c -\& -Add \c -.I directory\c -\& to the path to search for source files. -.PP - -.TP -.B \-nx -.TP -.B \-n -Do not execute commands from any `\|\c -.B .gdbinit\c -\&\|' initialization files. -Normally, the commands in these files are executed after all the -command options and arguments have been processed. - - -.TP -.B \-quiet -.TP -.B \-q -``Quiet''. Do not print the introductory and copyright messages. These -messages are also suppressed in batch mode. - -.TP -.B \-kernel -.TP -.B \-k -Puts GDB into kernel debugging mode. If no executable file is specified then -/kernel is used. If no core file is specified then /dev/mem is -used. Crash dumps can be examined by specifying both an executable and -a core file. - -.TP -.B \-wcore -.TP -.B \-w -This flag is only effective when debugging a "live" kernel. It makes the -core file (/dev/mem) writable so that kernel variables can be changed -during a debugging session. Use this with caution ! - -.TP -.B \-batch -Run in batch mode. Exit with status \c -.B 0\c -\& after processing all the command -files specified with `\|\c -.B \-x\c -\&\|' (and `\|\c -.B .gdbinit\c -\&\|', if not inhibited). -Exit with nonzero status if an error occurs in executing the GDB -commands in the command files. - -Batch mode may be useful for running GDB as a filter, for example to -download and run a program on another computer; in order to make this -more useful, the message -.sp -.br -Program\ exited\ normally. -.br -.sp - -(which is ordinarily issued whenever a program running under GDB control -terminates) is not issued when running in batch mode. - -.TP -.BI "\-cd=" "directory"\c -\& -Run GDB using \c -.I directory\c -\& as its working directory, -instead of the current directory. - -.TP -.B \-fullname -.TP -.B \-f -Emacs sets this option when it runs GDB as a subprocess. It tells GDB -to output the full file name and line number in a standard, -recognizable fashion each time a stack frame is displayed (which -includes each time the program stops). This recognizable format looks -like two `\|\c -.B \032\c -\&\|' characters, followed by the file name, line number -and character position separated by colons, and a newline. The -Emacs-to-GDB interface program uses the two `\|\c -.B \032\c -\&\|' characters as -a signal to display the source code for the frame. - -.TP -.BI "\-b " "bps"\c -\& -Set the line speed (baud rate or bits per second) of any serial -interface used by GDB for remote debugging. - -.TP -.BI "\-tty=" "device"\c -\& -Run using \c -.I device\c -\& for your program's standard input and output. -.PP - -.SH "SEE ALSO" -.RB "`\|" gdb "\|'" -entry in -.B info\c -\&; -.I -Using GDB: A Guide to the GNU Source-Level Debugger\c -, Richard M. Stallman and Roland H. Pesch, July 1991. -.SH COPYING -Copyright (c) 1991 Free Software Foundation, Inc. -.PP -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. -.PP -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. -.PP -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be included in -translations approved by the Free Software Foundation instead of in -the original English. diff --git a/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c b/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c deleted file mode 100644 index 323f751..0000000 --- a/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c +++ /dev/null @@ -1,802 +0,0 @@ -/* Native-dependent code for BSD Unix running on i386's, for GDB. - Copyright 1988, 1989, 1991, 1992 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. - - $FreeBSD$ -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "defs.h" -#include "symtab.h" - -/* this table must line up with REGISTER_NAMES in tm-i386v.h */ -/* symbols like 'tEAX' come from */ -static int tregmap[] = -{ - tEAX, tECX, tEDX, tEBX, - tESP, tEBP, tESI, tEDI, - tEIP, tEFLAGS, tCS, tSS, - tDS, tES, tSS, tSS, /* lies: no fs or gs */ -}; - -/* blockend is the value of u.u_ar0, and points to the - place where ES is stored. */ - -int -i386_register_u_addr (blockend, regnum) - int blockend; - int regnum; -{ - return (blockend + 4 * tregmap[regnum]); -} - - -#define fpstate save87 -#define U_FPSTATE(u) u.u_pcb.pcb_savefpu - -static void -i387_to_double (from, to) - char *from; - char *to; -{ - long *lp; - /* push extended mode on 387 stack, then pop in double mode - * - * first, set exception masks so no error is generated - - * number will be rounded to inf or 0, if necessary - */ - asm ("pushl %eax"); /* grab a stack slot */ - asm ("fstcw (%esp)"); /* get 387 control word */ - asm ("movl (%esp),%eax"); /* save old value */ - asm ("orl $0x3f,%eax"); /* mask all exceptions */ - asm ("pushl %eax"); - asm ("fldcw (%esp)"); /* load new value into 387 */ - - asm ("movl 8(%ebp),%eax"); - asm ("fldt (%eax)"); /* push extended number on 387 stack */ - asm ("fwait"); - asm ("movl 12(%ebp),%eax"); - asm ("fstpl (%eax)"); /* pop double */ - asm ("fwait"); - - asm ("popl %eax"); /* flush modified control word */ - asm ("fnclex"); /* clear exceptions */ - asm ("fldcw (%esp)"); /* restore original control word */ - asm ("popl %eax"); /* flush saved copy */ -} - -#if 0 -static void -double_to_i387 (from, to) - char *from; - char *to; -{ - /* push double mode on 387 stack, then pop in extended mode - * no errors are possible because every 64-bit pattern - * can be converted to an extended - */ - asm ("movl 8(%ebp),%eax"); - asm ("fldl (%eax)"); - asm ("fwait"); - asm ("movl 12(%ebp),%eax"); - asm ("fstpt (%eax)"); - asm ("fwait"); -} -#endif - -struct env387 -{ - unsigned short control; - unsigned short r0; - unsigned short status; - unsigned short r1; - unsigned short tag; - unsigned short r2; - unsigned long eip; - unsigned short code_seg; - unsigned short opcode; - unsigned long operand; - unsigned short operand_seg; - unsigned short r3; - unsigned char regs[8][10]; -}; - -/* static */ void -print_387_control_word (control) -unsigned int control; -{ - printf ("control 0x%04x: ", control); - printf ("compute to "); - switch ((control >> 8) & 3) - { - case 0: printf ("24 bits; "); break; - case 1: printf ("(bad); "); break; - case 2: printf ("53 bits; "); break; - case 3: printf ("64 bits; "); break; - } - printf ("round "); - switch ((control >> 10) & 3) - { - case 0: printf ("NEAREST; "); break; - case 1: printf ("DOWN; "); break; - case 2: printf ("UP; "); break; - case 3: printf ("CHOP; "); break; - } - if (control & 0x3f) - { - printf ("mask:"); - if (control & 0x0001) printf (" INVALID"); - if (control & 0x0002) printf (" DENORM"); - if (control & 0x0004) printf (" DIVZ"); - if (control & 0x0008) printf (" OVERF"); - if (control & 0x0010) printf (" UNDERF"); - if (control & 0x0020) printf (" LOS"); - printf (";"); - } - printf ("\n"); - if (control & 0xe080) printf ("warning: reserved bits on 0x%x\n", - control & 0xe080); -} - -/* static */ void -print_387_status_word (status) - unsigned int status; -{ - printf ("status 0x%04x: ", status); - if (status & 0xff) - { - printf ("exceptions:"); - if (status & 0x0001) printf (" INVALID"); - if (status & 0x0002) printf (" DENORM"); - if (status & 0x0004) printf (" DIVZ"); - if (status & 0x0008) printf (" OVERF"); - if (status & 0x0010) printf (" UNDERF"); - if (status & 0x0020) printf (" LOS"); - if (status & 0x0040) printf (" FPSTACK"); - printf ("; "); - } - printf ("flags: %d%d%d%d; ", - (status & 0x4000) != 0, - (status & 0x0400) != 0, - (status & 0x0200) != 0, - (status & 0x0100) != 0); - - printf ("top %d\n", (status >> 11) & 7); -} - -static void -print_387_status (status, ep) - unsigned short status; - struct env387 *ep; -{ - int i; - int bothstatus; - int top; - int fpreg; - unsigned char *p; - - bothstatus = ((status != 0) && (ep->status != 0)); - if (status != 0) - { - if (bothstatus) - printf ("u: "); - print_387_status_word ((unsigned int)status); - } - - if (ep->status != 0) - { - if (bothstatus) - printf ("e: "); - print_387_status_word ((unsigned int)ep->status); - } - - print_387_control_word ((unsigned int)ep->control); - printf ("opcode 0x%x; ", ep->opcode); - printf ("pc 0x%x:0x%x; ", ep->code_seg, ep->eip); - printf ("operand 0x%x:0x%x\n", ep->operand_seg, ep->operand); - - top = (ep->status >> 11) & 7; - - printf (" regno tag msb lsb value\n"); - for (fpreg = 7; fpreg >= 0; fpreg--) - { - int st_regno; - double val; - - /* The physical regno `fpreg' is only relevant as an index into the - * tag word. Logical `%st' numbers are required for indexing ep->regs. - */ - st_regno = (fpreg + 8 - top) & 7; - - printf ("%%st(%d) %s ", st_regno, fpreg == top ? "=>" : " "); - - switch ((ep->tag >> (fpreg * 2)) & 3) - { - case 0: printf ("valid "); break; - case 1: printf ("zero "); break; - case 2: printf ("trap "); break; - case 3: printf ("empty "); break; - } - for (i = 9; i >= 0; i--) - printf ("%02x", ep->regs[st_regno][i]); - - i387_to_double (ep->regs[st_regno], (char *)&val); - printf (" %g\n", val); - } -} - -void -i386_float_info () -{ - struct user u; /* just for address computations */ - int i; - /* fpstate defined in */ - struct fpstate *fpstatep; - char buf[sizeof (struct fpstate) + 2 * sizeof (int)]; - unsigned int uaddr; - char fpvalid; - unsigned int rounded_addr; - unsigned int rounded_size; - /*extern int corechan;*/ - int skip; - extern int inferior_pid; - - uaddr = (char *)&U_FPSTATE(u) - (char *)&u; - if (inferior_pid) - { - int *ip; - - rounded_addr = uaddr & -sizeof (int); - rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) + - sizeof (int) - 1) / sizeof (int); - skip = uaddr - rounded_addr; - - ip = (int *)buf; - for (i = 0; i < rounded_size; i++) - { - *ip++ = ptrace (PT_READ_U, inferior_pid, (caddr_t)rounded_addr, 0); - rounded_addr += sizeof (int); - } - } - else - { -#if 1 - printf("float info: can't do a core file (yet)\n"); - return; -#else - if (lseek (corechan, uaddr, 0) < 0) - perror_with_name ("seek on core file"); - if (myread (corechan, buf, sizeof (struct fpstate)) < 0) - perror_with_name ("read from core file"); - skip = 0; -#endif - } - - fpstatep = (struct fpstate *)(buf + skip); - print_387_status (fpstatep->sv_ex_sw, (struct env387 *)fpstatep); -} - -#ifdef SETUP_ARBITRARY_FRAME -FRAME -setup_arbitrary_frame (numargs, args) -int numargs; -unsigned int *args; -{ - if (numargs > 2) - error ("Too many args in frame specification"); - return create_new_frame ((CORE_ADDR)args[0], (CORE_ADDR)args[1]); -} -#endif - -#ifdef KERNEL_DEBUG -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#define KERNOFF ((unsigned)KERNBASE) -#define INKERNEL(x) ((x) >= KERNOFF) - -static CORE_ADDR sbr; -static CORE_ADDR curpcb; -static CORE_ADDR kstack; -static int found_pcb; -static int devmem; -static int kfd; -static struct pcb pcb; -int read_pcb (int, CORE_ADDR); -static CORE_ADDR kvtophys (int, CORE_ADDR); -static physrd(int, u_int, char*, int); - -extern CORE_ADDR ksym_lookup(const char *); - -/* substitutes for the stuff in libkvm which doesn't work */ -/* most of this was taken from the old kgdb */ - -/* we don't need all this stuff, but the call should look the same */ -kvm_open (efile, cfile, sfile, perm, errout) -char *efile; -char *cfile; -char *sfile; /* makes this kvm_open more compatible to the one in libkvm */ -int perm; -char *errout; /* makes this kvm_open more compatible to the one in libkvm */ -{ - struct stat stb; - CORE_ADDR addr; - int cfd; - - if ((cfd = open(cfile, perm, 0)) < 0) - return (cfd); - - fstat(cfd, &stb); - if ((stb.st_mode & S_IFMT) == S_IFCHR && stb.st_rdev == makedev(2, 0)) { - devmem = 1; - kfd = open ("/dev/kmem", perm, 0); - } - - physrd(cfd, ksym_lookup("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr); - printf("IdlePTD %x\n", sbr); - curpcb = ksym_lookup("curpcb") - KERNOFF; - physrd(cfd, curpcb, (char*)&curpcb, sizeof curpcb); - kstack = ksym_lookup("kstack"); - - found_pcb = 1; /* for vtophys */ - if (!devmem) - read_pcb(cfd, ksym_lookup("dumppcb") - KERNOFF); - else - read_pcb(cfd, kvtophys(cfd, kstack)); - - return (cfd); -} - -kvm_close (fd) -{ - return (close (fd)); -} - -kvm_write(core_kd, memaddr, myaddr, len) -CORE_ADDR memaddr; -char *myaddr; -{ - int cc; - - if (devmem) { - if (kfd > 0) { - /* - * Just like kvm_read, only we write. - */ - errno = 0; - if (lseek(kfd, (off_t)memaddr, 0) < 0 && errno != 0) { - error("kvm_write:invalid address (%x)", memaddr); - return (0); - } - cc = write(kfd, myaddr, len); - if (cc < 0) { - error("kvm_write:write failed"); - return (0); - } else if (cc < len) - error("kvm_write:short write"); - return (cc); - } else - return (0); - } else { - printf("kvm_write not implemented for dead kernels\n"); - return (0); - } - /* NOTREACHED */ -} - -kvm_read(core_kd, memaddr, myaddr, len) -CORE_ADDR memaddr; -char *myaddr; -{ - return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); -} - -kvm_uread(core_kd, p, memaddr, myaddr, len) -register struct proc *p; -CORE_ADDR memaddr; -char *myaddr; -{ - register char *cp; - char procfile[MAXPATHLEN]; - ssize_t amount; - int fd; - - if (devmem) { - cp = myaddr; - - sprintf(procfile, "/proc/%d/mem", p->p_pid); - fd = open(procfile, O_RDONLY, 0); - - if (fd < 0) { - error("cannot open %s", procfile); - close(fd); - return (0); - } - - while (len > 0) { - if (lseek(fd, memaddr, 0) == -1 && errno != 0) { - error("invalid address (%x) in %s", - memaddr, procfile); - break; - } - amount = read(fd, cp, len); - if (amount < 0) { - error("error reading %s", procfile); - break; - } - cp += amount; - memaddr += amount; - len -= amount; - } - - close(fd); - return (ssize_t)(cp - myaddr); - } else { - return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); - } -} - -static struct kinfo_proc kp; - -/* - * try to do what kvm_proclist in libkvm would do - */ -int -kvm_proclist (cfd, pid, p, cnt) -int cfd, pid, *cnt; -struct proc *p; -{ - struct proc lp; - - for (; p != NULL; p = lp.p_list.le_next) { - if (!kvm_read(cfd, (CORE_ADDR)p, (char *)&lp, sizeof (lp))) - return (0); - if (lp.p_pid != pid) - continue; - kp.kp_eproc.e_paddr = p; - *cnt = 1; - return (1); - } - *cnt = 0; - return (0); -} - -/* - * try to do what kvm_deadprocs in libkvm would do - */ -struct kinfo_proc * -kvm_deadprocs (cfd, pid, cnt) -int cfd, pid, *cnt; -{ - CORE_ADDR allproc, zombproc; - struct proc *p; - - allproc = ksym_lookup("allproc"); - if (kvm_read(cfd, allproc, (char *)&p, sizeof (p)) == 0) - return (NULL); - kvm_proclist (cfd, pid, p, cnt); - if (!*cnt) { - zombproc = ksym_lookup("zombproc"); - if (kvm_read(cfd, zombproc, (char *)&p, sizeof (p)) == 0) - return (NULL); - kvm_proclist (cfd, pid, p, cnt); - } - return (&kp); -} - -/* - * try to do what kvm_getprocs in libkvm would do - */ -struct kinfo_proc * -kvm_getprocs (cfd, op, proc, cnt) -int cfd, op, *cnt; -CORE_ADDR proc; -{ - int mib[4], size; - - *cnt = 0; - /* assume it's a pid */ - if (devmem) { /* "live" kernel, use sysctl */ - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = (int)proc; - size = sizeof (kp); - if (sysctl (mib, 4, &kp, &size, NULL, 0) < 0) { - perror("sysctl"); - *cnt = 0; - return (NULL); - } - if (!size) - *cnt = 0; - else - *cnt = 1; - return (&kp); - } else - return (kvm_deadprocs (cfd, (int)proc, cnt)); -} - -static -physrd(cfd, addr, dat, len) -u_int addr; -char *dat; -{ - if (lseek(cfd, (off_t)addr, L_SET) == -1) - return (-1); - return (read(cfd, dat, len)); -} - -static CORE_ADDR -kvtophys (fd, addr) -CORE_ADDR addr; -{ - CORE_ADDR v; - unsigned int pte; - static CORE_ADDR PTD = -1; - CORE_ADDR current_ptd; -#ifdef DEBUG_KVTOPHYS - CORE_ADDR oldaddr = addr; -#endif - - /* - * If we're looking at the kernel stack, - * munge the address to refer to the user space mapping instead; - * that way we get the requested process's kstack, not the running one. - */ - /* - * this breaks xlating user addresses from a crash dump so only - * do it for a "live" kernel. - */ - if (devmem && addr >= kstack && addr < kstack + ctob(UPAGES)) - addr = (addr - kstack) + curpcb; - - /* - * We may no longer have a linear system page table... - * - * Here's the scoop. IdlePTD contains the physical address - * of a page table directory that always maps the kernel. - * IdlePTD is in memory that is mapped 1-to-1, so we can - * find it easily given its 'virtual' address from ksym_lookup(). - * For hysterical reasons, the value of IdlePTD is stored in sbr. - * - * To look up a kernel address, we first convert it to a 1st-level - * address and look it up in IdlePTD. This gives us the physical - * address of a page table page; we extract the 2nd-level part of - * VA and read the 2nd-level pte. Finally, we add the offset part - * of the VA into the physical address from the pte and return it. - * - * User addresses are a little more complicated. If we don't have - * a current PCB from read_pcb(), we use PTD, which is the (fixed) - * virtual address of the current ptd. Since it's NOT in 1-to-1 - * kernel space, we must look it up using IdlePTD. If we do have - * a pcb, we get the ptd from pcb_ptd. - */ - - if (INKERNEL(addr)) - current_ptd = sbr; - else if (found_pcb == 0) { - if (PTD == -1) - PTD = kvtophys(fd, ksym_lookup("PTD")); - current_ptd = PTD; - } else - current_ptd = pcb.pcb_cr3; - - /* - * Read the first-level page table (ptd). - */ - v = current_ptd + ((unsigned)addr >> PDRSHIFT) * sizeof pte; - if (physrd(fd, v, (char *)&pte, sizeof pte) < 0 || (pte&PG_V) == 0) - return (~0); - - /* - * Read the second-level page table. - */ - v = (pte&PG_FRAME) + ((addr >> PAGE_SHIFT)&(NPTEPG-1)) * sizeof pte; - if (physrd(fd, v, (char *) &pte, sizeof(pte)) < 0 || (pte&PG_V) == 0) - return (~0); - - addr = (pte & PG_FRAME) + (addr & PAGE_MASK); -#ifdef DEBUG_KVTOPHYS - printf("vtophys(%x) -> %x\n", oldaddr, addr); -#endif - return (addr); -} - -read_pcb (fd, uaddr) -CORE_ADDR uaddr; -{ - int i; - int *pcb_regs = (int *)&pcb; - int eip; - CORE_ADDR nuaddr = uaddr; - - /* need this for the `proc' command to work */ - if (INKERNEL(uaddr)) - nuaddr = kvtophys(fd, uaddr); - if (physrd(fd, nuaddr, (char *)&pcb, sizeof pcb) < 0) { - error("cannot read pcb at %#x\n", uaddr); - return (-1); - } - printf("current pcb at %#x\n", uaddr); - - /* - * get the register values out of the sys pcb and - * store them where `read_register' will find them. - */ - for (i = 0; i < 8; ++i) - supply_register(i, &pcb_regs[i+10]); - supply_register(8, &pcb_regs[8]); /* eip */ - supply_register(9, &pcb_regs[9]); /* eflags */ - for (i = 10; i < 13; ++i) /* cs, ss, ds */ - supply_register(i, &pcb_regs[i+9]); - supply_register(13, &pcb_regs[18]); /* es */ - for (i = 14; i < 16; ++i) /* fs, gs */ - supply_register(i, &pcb_regs[i+8]); - -#if 0 /* doesn't work ??? */ - /* Hmm... */ - if (target_read_memory(pcb_regs[5+10]+4, &eip, sizeof eip, 0)) - error("Cannot read PC."); - supply_register(8, &eip); /* eip */ -#endif - - /* XXX 80387 registers? */ -} - -/* - * read len bytes from kernel virtual address 'addr' into local - * buffer 'buf'. Return numbert of bytes if read ok, 0 otherwise. On read - * errors, portion of buffer not read is zeroed. - */ -kernel_core_file_hook(fd, addr, buf, len) - CORE_ADDR addr; - char *buf; - int len; -{ - int i; - CORE_ADDR paddr; - register char *cp; - int cc; - - cp = buf; - - while (len > 0) { - paddr = kvtophys(fd, addr); -#ifdef DEBUG_KCFH -if(!INKERNEL(addr)) -fprintf(stderr,"addr 0x%x, paddr 0x%x\n", addr, paddr); -#endif - if (paddr == ~0) { - bzero(buf, len); - break; - } - /* we can't read across a page boundary */ - i = min(len, PAGE_SIZE - (addr & PAGE_MASK)); - if ((cc = physrd(fd, paddr, cp, i)) <= 0) { - bzero(cp, len); - return (cp - buf); - } - cp += cc; - addr += cc; - len -= cc; - } - return (cp - buf); -} - -/* - * The following is FreeBSD-specific hackery to decode special frames - * and elide the assembly-language stub. This could be made faster by - * defining a frame_type field in the machine-dependent frame information, - * but we don't think that's too important right now. - */ -enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall }; - -CORE_ADDR -fbsd_kern_frame_saved_pc (fr) -struct frame_info *fr; -{ - struct minimal_symbol *sym; - CORE_ADDR this_saved_pc; - enum frametype frametype; - - this_saved_pc = read_memory_integer (fr->frame + 4, 4); - sym = lookup_minimal_symbol_by_pc (this_saved_pc); - frametype = tf_normal; - if (sym != NULL) { - if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) - frametype = tf_trap; - else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) - frametype = tf_interrupt; - else if (strcmp (SYMBOL_NAME(sym), "Xsyscall") == 0) - frametype = tf_syscall; - } - - switch (frametype) { - case tf_normal: - return (this_saved_pc); - -#define oEIP offsetof(struct trapframe, tf_eip) - - case tf_trap: - return (read_memory_integer (fr->frame + 8 + oEIP, 4)); - - case tf_interrupt: - return (read_memory_integer (fr->frame + 16 + oEIP, 4)); - - case tf_syscall: - return (read_memory_integer (fr->frame + 8 + oEIP, 4)); -#undef oEIP - } -} - -CORE_ADDR -fbsd_kern_frame_chain (fr) -struct frame_info *fr; -{ - struct minimal_symbol *sym; - CORE_ADDR this_saved_pc; - enum frametype frametype; - - this_saved_pc = read_memory_integer (fr->frame + 4, 4); - sym = lookup_minimal_symbol_by_pc (this_saved_pc); - frametype = tf_normal; - if (sym != NULL) { - if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) - frametype = tf_trap; - else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) - frametype = tf_interrupt; - else if (strcmp (SYMBOL_NAME(sym), "_Xsyscall") == 0) - frametype = tf_syscall; - } - - switch (frametype) { - case tf_normal: - return (read_memory_integer (fr->frame, 4)); - -#define oEBP offsetof(struct trapframe, tf_ebp) - - case tf_trap: - return (read_memory_integer (fr->frame + 8 + oEBP, 4)); - - case tf_interrupt: - return (read_memory_integer (fr->frame + 16 + oEBP, 4)); - - case tf_syscall: - return (read_memory_integer (fr->frame + 8 + oEBP, 4)); -#undef oEBP - } -} - -#endif /* KERNEL_DEBUG */ diff --git a/gnu/usr.bin/binutils/gdb/i386/kvm-fbsd.c b/gnu/usr.bin/binutils/gdb/i386/kvm-fbsd.c new file mode 100644 index 0000000..9419b6a --- /dev/null +++ b/gnu/usr.bin/binutils/gdb/i386/kvm-fbsd.c @@ -0,0 +1,941 @@ +/* Live and postmortem kernel debugging functions for FreeBSD. + 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 +#include +#include +#include +#include +#include +#include +#include +#include "frame.h" /* required by inferior.h */ +#include "inferior.h" +#include "symtab.h" +#include "command.h" +#include "bfd.h" +#include "target.h" +#include "gdbcore.h" +#include +#include +#include +#include + +#include +#include +#include + +static void kcore_files_info PARAMS ((struct target_ops *)); + +static void kcore_close PARAMS ((int)); + +static void get_kcore_registers PARAMS ((int)); + +static int kcore_xfer_kmem PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *)); + +static int xfer_umem PARAMS ((CORE_ADDR, char *, int, int)); + +static CORE_ADDR ksym_lookup PARAMS ((const char *)); + +static int read_pcb PARAMS ((int, CORE_ADDR)); + +static struct proc * curProc PARAMS ((void)); + +static int set_proc_context PARAMS ((CORE_ADDR paddr)); + +static void kcore_open PARAMS ((char *filename, int from_tty)); + +static void kcore_detach PARAMS ((char *args, int from_tty)); + +static void set_proc_cmd PARAMS ((char *arg, int from_tty)); + +static CORE_ADDR kvtophys PARAMS ((int, CORE_ADDR)); + +static int physrd PARAMS ((int, u_int, char*, int)); + +static int kvm_open PARAMS ((const char *efile, char *cfile, char *sfile, + int perm, char *errout)); + +static int kvm_close PARAMS ((int fd)); + +static int kvm_write PARAMS ((int core_kd, CORE_ADDR memaddr, + char *myaddr, int len)); + +static int kvm_read PARAMS ((int core_kd, CORE_ADDR memaddr, + char *myaddr, int len)); + +static int kvm_uread PARAMS ((int core_kd, struct proc *p, + CORE_ADDR memaddr, char *myaddr, + int len)); + +static int kernel_core_file_hook PARAMS ((int fd, CORE_ADDR addr, + char *buf, int len)); + +static struct kinfo_proc * kvm_getprocs PARAMS ((int cfd, int op, + CORE_ADDR proc, int *cnt)); + +extern struct target_ops kcore_ops; /* Forward decl */ + +/* Non-zero means we are debugging a kernel core file */ +int kernel_debugging = 0; +int kernel_writablecore = 0; + +static char *core_file; +static int core_kd = -1; +static struct proc *cur_proc; +static CORE_ADDR kernel_start; + +/* + * Read the "thing" at kernel address 'addr' into the space pointed to + * by point. The length of the "thing" is determined by the type of p. + * Result is non-zero if transfer fails. + */ +#define kvread(addr, p) \ + (target_read_memory ((CORE_ADDR)(addr), (char *)(p), sizeof(*(p)))) + + + +/* + * The following is FreeBSD-specific hackery to decode special frames + * and elide the assembly-language stub. This could be made faster by + * defining a frame_type field in the machine-dependent frame information, + * but we don't think that's too important right now. + */ +enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall }; + +CORE_ADDR +fbsd_kern_frame_saved_pc (fr) +struct frame_info *fr; +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (fr->frame + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) { + if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) + frametype = tf_trap; + else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) + frametype = tf_interrupt; + else if (strcmp (SYMBOL_NAME(sym), "Xsyscall") == 0) + frametype = tf_syscall; + } + + switch (frametype) { + case tf_normal: + return (this_saved_pc); + +#define oEIP offsetof(struct trapframe, tf_eip) + + case tf_trap: + return (read_memory_integer (fr->frame + 8 + oEIP, 4)); + + case tf_interrupt: + return (read_memory_integer (fr->frame + 16 + oEIP, 4)); + + case tf_syscall: + return (read_memory_integer (fr->frame + 8 + oEIP, 4)); +#undef oEIP + } +} + +CORE_ADDR +fbsd_kern_frame_chain (fr) +struct frame_info *fr; +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (fr->frame + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) { + if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) + frametype = tf_trap; + else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) + frametype = tf_interrupt; + else if (strcmp (SYMBOL_NAME(sym), "_Xsyscall") == 0) + frametype = tf_syscall; + } + + switch (frametype) { + case tf_normal: + return (read_memory_integer (fr->frame, 4)); + +#define oEBP offsetof(struct trapframe, tf_ebp) + + case tf_trap: + return (read_memory_integer (fr->frame + 8 + oEBP, 4)); + + case tf_interrupt: + return (read_memory_integer (fr->frame + 16 + oEBP, 4)); + + case tf_syscall: + return (read_memory_integer (fr->frame + 8 + oEBP, 4)); +#undef oEBP + } +} + +static CORE_ADDR +ksym_lookup (name) +const char *name; +{ + struct minimal_symbol *sym; + + sym = lookup_minimal_symbol (name, NULL, NULL); + if (sym == NULL) + error ("kernel symbol `%s' not found.", name); + + return SYMBOL_VALUE_ADDRESS (sym); +} + +static struct proc * +curProc () +{ + struct proc *p; + CORE_ADDR addr = ksym_lookup ("curproc"); + + if (kvread (addr, &p)) + error ("cannot read proc pointer at %x\n", addr); + return p; +} + +/* + * Set the process context to that of the proc structure at + * system address paddr. + */ +static int +set_proc_context (paddr) + CORE_ADDR paddr; +{ + struct proc p; + + if (paddr < kernel_start) + return (1); + + cur_proc = (struct proc *)paddr; +#ifdef notyet + set_kernel_boundaries (cur_proc); +#endif + + /* Fetch all registers from core file */ + target_fetch_registers (-1); + + /* Now, set up the frame cache, and print the top of stack */ + flush_cached_frames (); + set_current_frame (create_new_frame (read_fp (), read_pc ())); + select_frame (get_current_frame (), 0); + return (0); +} + +/* Discard all vestiges of any previous core file + and mark data and stack spaces as empty. */ + +/* ARGSUSED */ +static void +kcore_close (quitting) + int quitting; +{ + inferior_pid = 0; /* Avoid confusion from thread stuff */ + + if (core_kd) + { + kvm_close (core_kd); + free (core_file); + core_file = NULL; + core_kd = -1; + } +} + +/* This routine opens and sets up the core file bfd */ + +static void +kcore_open (filename, from_tty) + char *filename; + int from_tty; +{ + const char *p; + struct cleanup *old_chain; + char buf[256], *cp; + int ontop; + CORE_ADDR addr; + struct pcb pcb; + + target_preopen (from_tty); + + unpush_target (&kcore_ops); + + if (!filename) + { + /*error (core_kd?*/ + error ( (core_kd >= 0)? + "No core file specified. (Use `detach' to stop debugging a core file.)" + : "No core file specified."); + } + + filename = tilde_expand (filename); + if (filename[0] != '/') + { + cp = concat (current_directory, "/", filename, NULL); + free (filename); + filename = cp; + } + + old_chain = make_cleanup (free, filename); + + /* + * gdb doesn't really do anything if the exec-file couldn't + * be opened (in that case exec_bfd is NULL). Usually that's + * no big deal, but kvm_open needs the exec-file's name, + * which results in dereferencing a NULL pointer, a real NO-NO ! + * So, check here if the open of the exec-file succeeded. + */ + if (exec_bfd == NULL) /* the open failed */ + error ("kgdb could not open the exec-file, please check the name you used !"); + + core_kd = kvm_open (exec_bfd->filename, filename, NULL, + kernel_writablecore? O_RDWR : O_RDONLY, "kgdb: "); + if (core_kd < 0) + perror_with_name (filename); + + /* Looks semi-reasonable. Toss the old core file and work on the new. */ + + discard_cleanups (old_chain); /* Don't free filename any more */ + core_file = filename; + ontop = !push_target (&kcore_ops); + + kernel_start = bfd_get_start_address (exec_bfd); /* XXX */ + + /* print out the panic string if there is one */ + if (kvread (ksym_lookup ("panicstr"), &addr) == 0 + && addr != 0 + && target_read_memory (addr, buf, sizeof (buf)) == 0) + { + for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++) + if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp))) + *cp = '?'; + *cp = '\0'; + if (buf[0] != '\0') + printf ("panic: %s\n", buf); + } + + if (!ontop) + { + warning ("you won't be able to access this core file until you terminate\n\ +your %s; do ``info files''", target_longname); + return; + } + + /* we may need this later */ + cur_proc = (struct proc *)curProc (); + /* Now, set up the frame cache, and print the top of stack */ + flush_cached_frames (); + set_current_frame (create_new_frame (read_fp (), read_pc ())); + select_frame (get_current_frame (), 0); + print_stack_frame (selected_frame, selected_frame_level, 1); +} + +static void +kcore_detach (args, from_tty) + char *args; + int from_tty; +{ + if (args) + error ("Too many arguments"); + unpush_target (&kcore_ops); + reinit_frame_cache (); + if (from_tty) + printf_filtered ("No kernel core file now.\n"); +} + +/* Get the registers out of a core file. This is the machine- + independent part. Fetch_core_registers is the machine-dependent + part, typically implemented in the xm-file for each architecture. */ + +/* We just get all the registers, so we don't use regno. */ +/* ARGSUSED */ +static void +get_kcore_registers (regno) + int regno; +{ + struct user *uaddr; + + /* find the pcb for the current process */ + if (kvread (&cur_proc->p_addr, &uaddr)) + error ("cannot read u area ptr for proc at %#x", cur_proc); + if (read_pcb (core_kd, (CORE_ADDR)&uaddr->u_pcb) < 0) + error ("cannot read pcb at %#x", &uaddr->u_pcb); +} + +static void +kcore_files_info (t) + struct target_ops *t; +{ + printf ("\t`%s'\n", core_file); +} + +static int +kcore_xfer_kmem (memaddr, myaddr, len, write, target) + CORE_ADDR memaddr; + char *myaddr; + int len; + int write; + struct target_ops *target; +{ + int n; + + if (!memaddr) + return (0); + + if (memaddr < kernel_start) + return xfer_umem (memaddr, myaddr, len, write); + + n = write ? + kvm_write (core_kd, memaddr, myaddr, len) : + kvm_read (core_kd, memaddr, myaddr, len) ; + + if (n < 0) + return 0; + return n; +} + +static int +xfer_umem (memaddr, myaddr, len, write) + CORE_ADDR memaddr; + char *myaddr; + int len; + int write; /* ignored */ +{ + int n; + struct proc proc; + + if (kvread (cur_proc, &proc)) + error ("cannot read proc at %#x", cur_proc); + n = kvm_uread (core_kd, &proc, memaddr, myaddr, len) ; + + if (n < 0) + return 0; + return n; +} + +static void +set_proc_cmd (arg, from_tty) + char *arg; + int from_tty; +{ + CORE_ADDR paddr; + struct kinfo_proc *kp; + int cnt = 0; + + if (!arg) + error_no_arg ("proc address for new current process"); + if (!kernel_debugging) + error ("not debugging kernel"); + + paddr = (CORE_ADDR)parse_and_eval_address (arg); + /* assume it's a proc pointer if it's in the kernel */ + if (paddr >= kernel_start) { + if (set_proc_context(paddr)) + error("invalid proc address"); + } else { + kp = kvm_getprocs(core_kd, KERN_PROC_PID, paddr, &cnt); + if (!cnt) + error("invalid pid"); + if (set_proc_context((CORE_ADDR)kp->kp_eproc.e_paddr)) + error("invalid proc address"); + } +} + + + +#define KERNOFF ((unsigned)KERNBASE) +#define INKERNEL(x) ((x) >= KERNOFF) + +static CORE_ADDR sbr; +static CORE_ADDR curpcb; +static CORE_ADDR kstack; +static int found_pcb; +static int devmem; +static int kfd; +static struct pcb pcb; + +/* substitutes for the stuff in libkvm which doesn't work */ +/* most of this was taken from the old kgdb */ + +/* we don't need all this stuff, but the call should look the same */ + +static int +kvm_open (efile, cfile, sfile, perm, errout) + const char *efile; + char *cfile; + char *sfile; /* makes this kvm_open more compatible to the one in libkvm */ + int perm; + char *errout; /* makes this kvm_open more compatible to the one in libkvm */ +{ + struct stat stb; + CORE_ADDR addr; + int cfd; + + if ((cfd = open (cfile, perm, 0)) < 0) + return (cfd); + + fstat (cfd, &stb); + if ((stb.st_mode & S_IFMT) == S_IFCHR + && stb.st_rdev == makedev (2, 0)) + { + devmem = 1; + kfd = open ("/dev/kmem", perm, 0); + } + + physrd (cfd, ksym_lookup ("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr); + printf ("IdlePTD %x\n", sbr); + curpcb = ksym_lookup ("curpcb") - KERNOFF; + physrd (cfd, curpcb, (char*)&curpcb, sizeof curpcb); + kstack = ksym_lookup ("kstack"); + + found_pcb = 1; /* for vtophys */ + if (!devmem) + read_pcb (cfd, ksym_lookup ("dumppcb") - KERNOFF); + else + read_pcb (cfd, kvtophys (cfd, kstack)); + + return (cfd); +} + +static int +kvm_close (fd) + int fd; +{ + return (close (fd)); +} + +static int +kvm_write (core_kd, memaddr, myaddr, len) + int core_kd; + CORE_ADDR memaddr; + char *myaddr; +{ + int cc; + + if (devmem) + { + if (kfd > 0) + { + /* + * Just like kvm_read, only we write. + */ + errno = 0; + if (lseek (kfd, (off_t)memaddr, 0) < 0 + && errno != 0) + { + error ("kvm_write:invalid address (%x)", memaddr); + return (0); + } + cc = write (kfd, myaddr, len); + if (cc < 0) + { + error ("kvm_write:write failed"); + return (0); + } + else if (cc < len) + error ("kvm_write:short write"); + return (cc); + } + else + return (0); + } + else + { + printf ("kvm_write not implemented for dead kernels\n"); + return (0); + } + /* NOTREACHED */ +} + +static int +kvm_read (core_kd, memaddr, myaddr, len) + int core_kd; + CORE_ADDR memaddr; + char *myaddr; +{ + return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); +} + +static int +kvm_uread (core_kd, p, memaddr, myaddr, len) + int core_kd; + register struct proc *p; + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register char *cp; + char procfile[MAXPATHLEN]; + ssize_t amount; + int fd; + + if (devmem) + { + cp = myaddr; + + sprintf (procfile, "/proc/%d/mem", p->p_pid); + fd = open (procfile, O_RDONLY, 0); + + if (fd < 0) + { + error ("cannot open %s", procfile); + close (fd); + return (0); + } + + while (len > 0) + { + if (lseek (fd, memaddr, 0) == -1 && errno != 0) + { + error ("invalid address (%x) in %s", + memaddr, procfile); + break; + } + amount = read (fd, cp, len); + if (amount < 0) + { + error ("error reading %s", procfile); + break; + } + cp += amount; + memaddr += amount; + len -= amount; + } + + close (fd); + return (ssize_t) (cp - myaddr); + } + else + return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); +} + +static struct kinfo_proc kp; + +/* + * try to do what kvm_proclist in libkvm would do + */ +static int +kvm_proclist (cfd, pid, p, cnt) +int cfd, pid, *cnt; +struct proc *p; +{ + struct proc lp; + + for (; p != NULL; p = lp.p_list.le_next) { + if (!kvm_read(cfd, (CORE_ADDR)p, (char *)&lp, sizeof (lp))) + return (0); + if (lp.p_pid != pid) + continue; + kp.kp_eproc.e_paddr = p; + *cnt = 1; + return (1); + } + *cnt = 0; + return (0); +} + +/* + * try to do what kvm_deadprocs in libkvm would do + */ +static struct kinfo_proc * +kvm_deadprocs (cfd, pid, cnt) +int cfd, pid, *cnt; +{ + CORE_ADDR allproc, zombproc; + struct proc *p; + + allproc = ksym_lookup("allproc"); + if (kvm_read(cfd, allproc, (char *)&p, sizeof (p)) == 0) + return (NULL); + kvm_proclist (cfd, pid, p, cnt); + if (!*cnt) { + zombproc = ksym_lookup("zombproc"); + if (kvm_read(cfd, zombproc, (char *)&p, sizeof (p)) == 0) + return (NULL); + kvm_proclist (cfd, pid, p, cnt); + } + return (&kp); +} + +/* + * try to do what kvm_getprocs in libkvm would do + */ +static struct kinfo_proc * +kvm_getprocs (cfd, op, proc, cnt) +int cfd, op, *cnt; +CORE_ADDR proc; +{ + int mib[4], size; + + *cnt = 0; + /* assume it's a pid */ + if (devmem) { /* "live" kernel, use sysctl */ + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = (int)proc; + size = sizeof (kp); + if (sysctl (mib, 4, &kp, &size, NULL, 0) < 0) { + perror("sysctl"); + *cnt = 0; + return (NULL); + } + if (!size) + *cnt = 0; + else + *cnt = 1; + return (&kp); + } else + return (kvm_deadprocs (cfd, (int)proc, cnt)); +} + +static int +physrd (cfd, addr, dat, len) + int cfd; + u_int addr; + char *dat; + int len; +{ + if (lseek (cfd, (off_t)addr, L_SET) == -1) + return (-1); + return (read (cfd, dat, len)); +} + +static CORE_ADDR +kvtophys (fd, addr) + int fd; + CORE_ADDR addr; +{ + CORE_ADDR v; + unsigned int pte; + static CORE_ADDR PTD = -1; + CORE_ADDR current_ptd; + + /* + * If we're looking at the kernel stack, + * munge the address to refer to the user space mapping instead; + * that way we get the requested process's kstack, not the running one. + */ + /* + * this breaks xlating user addresses from a crash dump so only + * do it for a "live" kernel. + */ + if (devmem && addr >= kstack && addr < kstack + ctob (UPAGES)) + addr = (addr - kstack) + curpcb; + + /* + * We may no longer have a linear system page table... + * + * Here's the scoop. IdlePTD contains the physical address + * of a page table directory that always maps the kernel. + * IdlePTD is in memory that is mapped 1-to-1, so we can + * find it easily given its 'virtual' address from ksym_lookup(). + * For hysterical reasons, the value of IdlePTD is stored in sbr. + * + * To look up a kernel address, we first convert it to a 1st-level + * address and look it up in IdlePTD. This gives us the physical + * address of a page table page; we extract the 2nd-level part of + * VA and read the 2nd-level pte. Finally, we add the offset part + * of the VA into the physical address from the pte and return it. + * + * User addresses are a little more complicated. If we don't have + * a current PCB from read_pcb(), we use PTD, which is the (fixed) + * virtual address of the current ptd. Since it's NOT in 1-to-1 + * kernel space, we must look it up using IdlePTD. If we do have + * a pcb, we get the ptd from pcb_ptd. + */ + + if (INKERNEL (addr)) + current_ptd = sbr; + else if (found_pcb == 0) + { + if (PTD == -1) + PTD = kvtophys (fd, ksym_lookup ("PTD")); + current_ptd = PTD; + } + else + current_ptd = pcb.pcb_cr3; + + /* + * Read the first-level page table (ptd). + */ + v = current_ptd + ( (unsigned)addr >> PDRSHIFT) * sizeof pte; + if (physrd (fd, v, (char *)&pte, sizeof pte) < 0 || (pte&PG_V) == 0) + return (~0); + + /* + * Read the second-level page table. + */ + v = (pte&PG_FRAME) + ((addr >> PAGE_SHIFT)&(NPTEPG-1)) * sizeof pte; + if (physrd (fd, v, (char *) &pte, sizeof (pte)) < 0 || (pte&PG_V) == 0) + return (~0); + + addr = (pte & PG_FRAME) + (addr & PAGE_MASK); +#if 0 + printf ("vtophys (%x) -> %x\n", oldaddr, addr); +#endif + return (addr); +} + +static int +read_pcb (fd, uaddr) + int fd; + CORE_ADDR uaddr; +{ + int i; + int *pcb_regs = (int *)&pcb; + int eip; + CORE_ADDR nuaddr = uaddr; + + /* need this for the `proc' command to work */ + if (INKERNEL(uaddr)) + nuaddr = kvtophys(fd, uaddr); + + if (physrd (fd, nuaddr, (char *)&pcb, sizeof pcb) < 0) + { + error ("cannot read pcb at %x\n", uaddr); + return (-1); + } + printf ("current pcb at %x\n", uaddr); + + /* + * get the register values out of the sys pcb and + * store them where `read_register' will find them. + */ + for (i = 0; i < 8; ++i) + supply_register (i, (char *)&pcb_regs[i+10]); + supply_register (8, (char *)&pcb_regs[8]); /* eip */ + supply_register (9, (char *)&pcb_regs[9]); /* eflags */ + for (i = 10; i < 13; ++i) /* cs, ss, ds */ + supply_register (i, (char *)&pcb_regs[i+9]); + supply_register (13, (char *)&pcb_regs[18]); /* es */ + for (i = 14; i < 16; ++i) /* fs, gs */ + supply_register (i, (char *)&pcb_regs[i+8]); + +#if 0 /* doesn't work ??? */ + /* Hmm... */ + if (target_read_memory (pcb_regs[5+10]+4, &eip, sizeof eip, 0)) + error ("Cannot read PC."); + supply_register (8, (char *)&eip); /* eip */ +#endif + + /* XXX 80387 registers? */ +} + +/* + * read len bytes from kernel virtual address 'addr' into local + * buffer 'buf'. Return numbert of bytes if read ok, 0 otherwise. On read + * errors, portion of buffer not read is zeroed. + */ + +static int +kernel_core_file_hook (fd, addr, buf, len) + int fd; + CORE_ADDR addr; + char *buf; + int len; +{ + int i; + CORE_ADDR paddr; + register char *cp; + int cc; + + cp = buf; + + while (len > 0) + { + paddr = kvtophys (fd, addr); + if (paddr == ~0) + { + memset (buf, '\000', len); + break; + } + /* we can't read across a page boundary */ + i = min (len, PAGE_SIZE - (addr & PAGE_MASK)); + if ( (cc = physrd (fd, paddr, cp, i)) <= 0) + { + memset (cp, '\000', len); + return (cp - buf); + } + cp += cc; + addr += cc; + len -= cc; + } + return (cp - buf); +} + +struct target_ops kcore_ops = { + "kcore", /* to_shortname */ + "Kernel core dump file", /* to_longname */ + "Use a core file as a target. Specify the filename of the core file.", /* to_doc */ + kcore_open, /* to_open */ + kcore_close, /* to_close */ + find_default_attach, /* to_attach */ + kcore_detach, /* to_detach */ + NULL, /* to_resume */ + NULL, /* to_wait */ + get_kcore_registers, /* to_fetch_registers */ + NULL, /* to_store_registers */ + NULL, /* to_prepare_to_store */ + kcore_xfer_kmem, /* to_xfer_memory */ + kcore_files_info, /* 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 */ + NULL, /* to_kill */ + NULL, /* to_load */ + NULL, /* to_lookup_symbol */ + find_default_create_inferior, /* to_create_inferior */ + NULL, /* to_mourn_inferior */ + 0, /* to_can_run */ + 0, /* to_notice_signals */ + NULL, /* to_thread_alive */ + 0, /* to_stop */ + kcore_stratum, /* to_stratum */ + NULL, /* to_next */ + 0, /* 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 */ +}; + +void +_initialize_kcorelow() +{ + add_target (&kcore_ops); + add_com ("proc", class_obscure, set_proc_cmd, "Set current process context"); +} diff --git a/gnu/usr.bin/binutils/gdb/i386/nm.h b/gnu/usr.bin/binutils/gdb/i386/nm.h index ec85bd8..6affe1a 100644 --- a/gnu/usr.bin/binutils/gdb/i386/nm.h +++ b/gnu/usr.bin/binutils/gdb/i386/nm.h @@ -1,5 +1,5 @@ /* Native-dependent definitions for Intel 386 running BSD Unix, for GDB. - Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc. + Copyright 1986, 1987, 1989, 1992, 1996 Free Software Foundation, Inc. This file is part of GDB. @@ -15,10 +15,12 @@ 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef NM_FREEBSD_H -#define NM_FREEBSD_H +#ifndef NM_FBSD_H +#define NM_FBSD_H + +#define ATTACH_DETACH /* Be shared lib aware */ #include "solib.h" @@ -29,10 +31,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #define KERNEL_U_ADDR USRSTACK -/* #undef FLOAT_INFO */ /* No float info yet */ -#define FLOAT_INFO extern void i386_float_info (); \ - i386_float_info () - #define REGISTER_U_ADDR(addr, blockend, regno) \ (addr) = i386_register_u_addr ((blockend),(regno)); @@ -40,61 +38,81 @@ extern int i386_register_u_addr PARAMS ((int, int)); #define PTRACE_ARG3_TYPE char* -#define ATTACH_DETACH -#define KERNEL_DEBUG /* make structure definitions match up with those expected in solib.c */ - -#define link_object sod -#define lo_name sod_name -#define lo_library sod_library -#define lo_unused sod_reserved -#define lo_major sod_major -#define lo_minor sod_minor -#define lo_next sod_next - -#define link_map so_map -#define lm_addr som_addr -#define lm_name som_path -#define lm_next som_next -#define lm_lop som_sod -#define lm_lob som_sodbase -#define lm_rwt som_write -#define lm_ld som_dynamic -#define lm_lpd som_spd - -#define link_dynamic_2 section_dispatch_table -#define ld_loaded sdt_loaded -#define ld_need sdt_sods -#define ld_rules sdt_filler1 -#define ld_got sdt_got -#define ld_plt sdt_plt -#define ld_rel sdt_rel -#define ld_hash sdt_hash -#define ld_stab sdt_nzlist -#define ld_stab_hash sdt_filler2 -#define ld_buckets sdt_buckets -#define ld_symbols sdt_strings -#define ld_symb_size sdt_str_sz -#define ld_text sdt_text_sz -#define ld_plt_sz sdt_plt_sz - -#define rtc_symb rt_symbol -#define rtc_sp rt_sp -#define rtc_next rt_next - -#define ld_debug so_debug -#define ldd_version dd_version -#define ldd_in_debugger dd_in_debugger -#define ldd_sym_loaded dd_sym_loaded -#define ldd_bp_addr dd_bpt_addr -#define ldd_bp_inst dd_bpt_shadow -#define ldd_cp dd_cc - -#define link_dynamic _dynamic -#define ld_version d_version -#define ldd d_debug -#define ld_un d_un -#define ld_2 d_sdt - -#endif /* NM_FREEBSD_H */ +#define link_object sod +#define lo_name sod_name +#define lo_library sod_library +#define lo_unused sod_reserved +#define lo_major sod_major +#define lo_minor sod_minor +#define lo_next sod_next + +#define link_map so_map +#define lm_addr som_addr +#define lm_name som_path +#define lm_next som_next +#define lm_lop som_sod +#define lm_lob som_sodbase +#define lm_rwt som_write +#define lm_ld som_dynamic +#define lm_lpd som_spd + +#define link_dynamic_2 section_dispatch_table +#define ld_loaded sdt_loaded +#define ld_need sdt_sods +#define ld_rules sdt_filler1 +#define ld_got sdt_got +#define ld_plt sdt_plt +#define ld_rel sdt_rel +#define ld_hash sdt_hash +#define ld_stab sdt_nzlist +#define ld_stab_hash sdt_filler2 +#define ld_buckets sdt_buckets +#define ld_symbols sdt_strings +#define ld_symb_size sdt_str_sz +#define ld_text sdt_text_sz +#define ld_plt_sz sdt_plt_sz + +#define rtc_symb rt_symbol +#define rtc_sp rt_sp +#define rtc_next rt_next + +#define ld_debug so_debug +#define ldd_version dd_version +#define ldd_in_debugger dd_in_debugger +#define ldd_sym_loaded dd_sym_loaded +#define ldd_bp_addr dd_bpt_addr +#define ldd_bp_inst dd_bpt_shadow +#define ldd_cp dd_cc + +#define link_dynamic _dynamic +#define ld_version d_version +#define ldd d_debug +#define ld_un d_un +#define ld_2 d_sdt + +/* 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)); + +#define ADDITIONAL_OPTIONS \ + {"kernel", no_argument, &kernel_debugging, 1}, \ + {"k", no_argument, &kernel_debugging, 1}, \ + {"wcore", no_argument, &kernel_writablecore, 1}, \ + {"w", no_argument, &kernel_writablecore, 1}, + +#define ADDITIONAL_OPTION_HELP \ + "\ + --kernel Enable kernel debugging.\n\ + --wcore Make core file writable (only works for /dev/mem).\n\ + This option only works while debugging a kernel !!\n\ +" + +extern int kernel_debugging; +extern int kernel_writablecore; + +#define DEFAULT_PROMPT kernel_debugging?"(kgdb) ":"(gdb) " + +#endif /* NM_FBSD_H */ diff --git a/gnu/usr.bin/binutils/gdb/i386/tm.h b/gnu/usr.bin/binutils/gdb/i386/tm.h index f775da9..6b1dc06 100644 --- a/gnu/usr.bin/binutils/gdb/i386/tm.h +++ b/gnu/usr.bin/binutils/gdb/i386/tm.h @@ -1,5 +1,5 @@ -/* Macro definitions for i386 running under BSD Unix. - Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. +/* Macro definitions for x86 running under FreeBSD Unix. + Copyright 1996 Free Software Foundation, Inc. This file is part of GDB. @@ -15,43 +15,33 @@ 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _FREEBSD_TM_H_ -#define _FREEBSD_TM_H_ -/* Override number of expected traps from sysv. */ -#define START_INFERIOR_TRAPS_EXPECTED 2 +#ifndef TM_FBSD_H +#define TM_FBSD_H 1 -/* Most definitions from sysv could be used. */ -#include "tm-i386v.h" +#include "i386/tm-i386bsd.h" -/* 386BSD cannot handle the segment registers. */ -/* BSDI can't handle them either. */ -/* FreeBSD cannot handle %fs or %gs. */ #undef NUM_REGS -#ifdef __FreeBSD__ #define NUM_REGS 14 -#else -#define NUM_REGS 10 -#endif -/* 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 +extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *)); -/* The following redefines make backtracing through sigtramp work. - They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp - from the sigcontext structure which is pushed by the kernel on the - user stack, along with a pointer to it. */ +#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv) + +extern void i386_float_info PARAMS ((void)); + +#define FLOAT_INFO i386_float_info () + +#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) STREQ (name, "_DYNAMIC") /* FRAME_CHAIN takes a frame's nominal address and produces the frame's chain-pointer. In the case of the i386, the frame's nominal address is the address of a 4-byte word containing the calling frame's address. */ -#undef FRAME_CHAIN + extern CORE_ADDR fbsd_kern_frame_chain (struct frame_info *); +#undef FRAME_CHAIN #define FRAME_CHAIN(thisframe) \ (kernel_debugging ? fbsd_kern_frame_chain(thisframe) : \ ((thisframe)->signal_handler_caller \ @@ -60,25 +50,10 @@ extern CORE_ADDR fbsd_kern_frame_chain (struct frame_info *); ? read_memory_integer ((thisframe)->frame, 4) \ : 0))) -/* 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. */ -#undef FRAMELESS_FUNCTION_INVOCATION -#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \ - do { \ - if ((FI)->signal_handler_caller) \ - (FRAMELESS) = 0; \ - else \ - (FRAMELESS) = frameless_look_for_prologue(FI); \ - } while (0) - /* Saved Pc. Get it from sigcontext if within sigtramp. */ -/* Offset to saved PC in sigcontext, from . */ -#define SIGCONTEXT_PC_OFFSET 20 - -#undef FRAME_SAVED_PC extern CORE_ADDR fbsd_kern_frame_saved_pc (struct frame_info *); +#undef FRAME_SAVED_PC #define FRAME_SAVED_PC(FRAME) \ (kernel_debugging ? fbsd_kern_frame_saved_pc(FRAME) : \ (((FRAME)->signal_handler_caller \ @@ -86,9 +61,4 @@ extern CORE_ADDR fbsd_kern_frame_saved_pc (struct frame_info *); : read_memory_integer ((FRAME)->frame + 4, 4)) \ )) -#undef SETUP_ARBITRARY_FRAME -#include "frame.h" -extern FRAME setup_arbitrary_frame (); -#define SETUP_ARBITRARY_FRAME setup_arbitrary_frame - -#endif /* _FREEBSD_TM_H_ */ +#endif /* TM_FBSD_H */ diff --git a/gnu/usr.bin/binutils/gdb/i386/version.c b/gnu/usr.bin/binutils/gdb/i386/version.c index 43f63d2..3d677fe 100644 --- a/gnu/usr.bin/binutils/gdb/i386/version.c +++ b/gnu/usr.bin/binutils/gdb/i386/version.c @@ -1,3 +1,3 @@ -char *version = "4.13"; +char *version = "4.16"; char *host_name = "i386-unknown-freebsd"; char *target_name = "i386-unknown-freebsd"; diff --git a/gnu/usr.bin/binutils/gdb/i386/xm.h b/gnu/usr.bin/binutils/gdb/i386/xm.h index 6a71227..8a852a2 100644 --- a/gnu/usr.bin/binutils/gdb/i386/xm.h +++ b/gnu/usr.bin/binutils/gdb/i386/xm.h @@ -15,15 +15,9 @@ 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define HOST_BYTE_ORDER LITTLE_ENDIAN #include /* for INT_MIN, to avoid "INT_MIN redefined" warnings from defs.h */ - -/* psignal() is in . */ - -#define PSIGNAL_IN_SIGNAL_H - -#define HAVE_TERMIOS diff --git a/gnu/usr.bin/binutils/gdb/kvm-fbsd.c b/gnu/usr.bin/binutils/gdb/kvm-fbsd.c new file mode 100644 index 0000000..9419b6a --- /dev/null +++ b/gnu/usr.bin/binutils/gdb/kvm-fbsd.c @@ -0,0 +1,941 @@ +/* Live and postmortem kernel debugging functions for FreeBSD. + 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 +#include +#include +#include +#include +#include +#include +#include +#include "frame.h" /* required by inferior.h */ +#include "inferior.h" +#include "symtab.h" +#include "command.h" +#include "bfd.h" +#include "target.h" +#include "gdbcore.h" +#include +#include +#include +#include + +#include +#include +#include + +static void kcore_files_info PARAMS ((struct target_ops *)); + +static void kcore_close PARAMS ((int)); + +static void get_kcore_registers PARAMS ((int)); + +static int kcore_xfer_kmem PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *)); + +static int xfer_umem PARAMS ((CORE_ADDR, char *, int, int)); + +static CORE_ADDR ksym_lookup PARAMS ((const char *)); + +static int read_pcb PARAMS ((int, CORE_ADDR)); + +static struct proc * curProc PARAMS ((void)); + +static int set_proc_context PARAMS ((CORE_ADDR paddr)); + +static void kcore_open PARAMS ((char *filename, int from_tty)); + +static void kcore_detach PARAMS ((char *args, int from_tty)); + +static void set_proc_cmd PARAMS ((char *arg, int from_tty)); + +static CORE_ADDR kvtophys PARAMS ((int, CORE_ADDR)); + +static int physrd PARAMS ((int, u_int, char*, int)); + +static int kvm_open PARAMS ((const char *efile, char *cfile, char *sfile, + int perm, char *errout)); + +static int kvm_close PARAMS ((int fd)); + +static int kvm_write PARAMS ((int core_kd, CORE_ADDR memaddr, + char *myaddr, int len)); + +static int kvm_read PARAMS ((int core_kd, CORE_ADDR memaddr, + char *myaddr, int len)); + +static int kvm_uread PARAMS ((int core_kd, struct proc *p, + CORE_ADDR memaddr, char *myaddr, + int len)); + +static int kernel_core_file_hook PARAMS ((int fd, CORE_ADDR addr, + char *buf, int len)); + +static struct kinfo_proc * kvm_getprocs PARAMS ((int cfd, int op, + CORE_ADDR proc, int *cnt)); + +extern struct target_ops kcore_ops; /* Forward decl */ + +/* Non-zero means we are debugging a kernel core file */ +int kernel_debugging = 0; +int kernel_writablecore = 0; + +static char *core_file; +static int core_kd = -1; +static struct proc *cur_proc; +static CORE_ADDR kernel_start; + +/* + * Read the "thing" at kernel address 'addr' into the space pointed to + * by point. The length of the "thing" is determined by the type of p. + * Result is non-zero if transfer fails. + */ +#define kvread(addr, p) \ + (target_read_memory ((CORE_ADDR)(addr), (char *)(p), sizeof(*(p)))) + + + +/* + * The following is FreeBSD-specific hackery to decode special frames + * and elide the assembly-language stub. This could be made faster by + * defining a frame_type field in the machine-dependent frame information, + * but we don't think that's too important right now. + */ +enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall }; + +CORE_ADDR +fbsd_kern_frame_saved_pc (fr) +struct frame_info *fr; +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (fr->frame + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) { + if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) + frametype = tf_trap; + else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) + frametype = tf_interrupt; + else if (strcmp (SYMBOL_NAME(sym), "Xsyscall") == 0) + frametype = tf_syscall; + } + + switch (frametype) { + case tf_normal: + return (this_saved_pc); + +#define oEIP offsetof(struct trapframe, tf_eip) + + case tf_trap: + return (read_memory_integer (fr->frame + 8 + oEIP, 4)); + + case tf_interrupt: + return (read_memory_integer (fr->frame + 16 + oEIP, 4)); + + case tf_syscall: + return (read_memory_integer (fr->frame + 8 + oEIP, 4)); +#undef oEIP + } +} + +CORE_ADDR +fbsd_kern_frame_chain (fr) +struct frame_info *fr; +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (fr->frame + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) { + if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) + frametype = tf_trap; + else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) + frametype = tf_interrupt; + else if (strcmp (SYMBOL_NAME(sym), "_Xsyscall") == 0) + frametype = tf_syscall; + } + + switch (frametype) { + case tf_normal: + return (read_memory_integer (fr->frame, 4)); + +#define oEBP offsetof(struct trapframe, tf_ebp) + + case tf_trap: + return (read_memory_integer (fr->frame + 8 + oEBP, 4)); + + case tf_interrupt: + return (read_memory_integer (fr->frame + 16 + oEBP, 4)); + + case tf_syscall: + return (read_memory_integer (fr->frame + 8 + oEBP, 4)); +#undef oEBP + } +} + +static CORE_ADDR +ksym_lookup (name) +const char *name; +{ + struct minimal_symbol *sym; + + sym = lookup_minimal_symbol (name, NULL, NULL); + if (sym == NULL) + error ("kernel symbol `%s' not found.", name); + + return SYMBOL_VALUE_ADDRESS (sym); +} + +static struct proc * +curProc () +{ + struct proc *p; + CORE_ADDR addr = ksym_lookup ("curproc"); + + if (kvread (addr, &p)) + error ("cannot read proc pointer at %x\n", addr); + return p; +} + +/* + * Set the process context to that of the proc structure at + * system address paddr. + */ +static int +set_proc_context (paddr) + CORE_ADDR paddr; +{ + struct proc p; + + if (paddr < kernel_start) + return (1); + + cur_proc = (struct proc *)paddr; +#ifdef notyet + set_kernel_boundaries (cur_proc); +#endif + + /* Fetch all registers from core file */ + target_fetch_registers (-1); + + /* Now, set up the frame cache, and print the top of stack */ + flush_cached_frames (); + set_current_frame (create_new_frame (read_fp (), read_pc ())); + select_frame (get_current_frame (), 0); + return (0); +} + +/* Discard all vestiges of any previous core file + and mark data and stack spaces as empty. */ + +/* ARGSUSED */ +static void +kcore_close (quitting) + int quitting; +{ + inferior_pid = 0; /* Avoid confusion from thread stuff */ + + if (core_kd) + { + kvm_close (core_kd); + free (core_file); + core_file = NULL; + core_kd = -1; + } +} + +/* This routine opens and sets up the core file bfd */ + +static void +kcore_open (filename, from_tty) + char *filename; + int from_tty; +{ + const char *p; + struct cleanup *old_chain; + char buf[256], *cp; + int ontop; + CORE_ADDR addr; + struct pcb pcb; + + target_preopen (from_tty); + + unpush_target (&kcore_ops); + + if (!filename) + { + /*error (core_kd?*/ + error ( (core_kd >= 0)? + "No core file specified. (Use `detach' to stop debugging a core file.)" + : "No core file specified."); + } + + filename = tilde_expand (filename); + if (filename[0] != '/') + { + cp = concat (current_directory, "/", filename, NULL); + free (filename); + filename = cp; + } + + old_chain = make_cleanup (free, filename); + + /* + * gdb doesn't really do anything if the exec-file couldn't + * be opened (in that case exec_bfd is NULL). Usually that's + * no big deal, but kvm_open needs the exec-file's name, + * which results in dereferencing a NULL pointer, a real NO-NO ! + * So, check here if the open of the exec-file succeeded. + */ + if (exec_bfd == NULL) /* the open failed */ + error ("kgdb could not open the exec-file, please check the name you used !"); + + core_kd = kvm_open (exec_bfd->filename, filename, NULL, + kernel_writablecore? O_RDWR : O_RDONLY, "kgdb: "); + if (core_kd < 0) + perror_with_name (filename); + + /* Looks semi-reasonable. Toss the old core file and work on the new. */ + + discard_cleanups (old_chain); /* Don't free filename any more */ + core_file = filename; + ontop = !push_target (&kcore_ops); + + kernel_start = bfd_get_start_address (exec_bfd); /* XXX */ + + /* print out the panic string if there is one */ + if (kvread (ksym_lookup ("panicstr"), &addr) == 0 + && addr != 0 + && target_read_memory (addr, buf, sizeof (buf)) == 0) + { + for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++) + if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp))) + *cp = '?'; + *cp = '\0'; + if (buf[0] != '\0') + printf ("panic: %s\n", buf); + } + + if (!ontop) + { + warning ("you won't be able to access this core file until you terminate\n\ +your %s; do ``info files''", target_longname); + return; + } + + /* we may need this later */ + cur_proc = (struct proc *)curProc (); + /* Now, set up the frame cache, and print the top of stack */ + flush_cached_frames (); + set_current_frame (create_new_frame (read_fp (), read_pc ())); + select_frame (get_current_frame (), 0); + print_stack_frame (selected_frame, selected_frame_level, 1); +} + +static void +kcore_detach (args, from_tty) + char *args; + int from_tty; +{ + if (args) + error ("Too many arguments"); + unpush_target (&kcore_ops); + reinit_frame_cache (); + if (from_tty) + printf_filtered ("No kernel core file now.\n"); +} + +/* Get the registers out of a core file. This is the machine- + independent part. Fetch_core_registers is the machine-dependent + part, typically implemented in the xm-file for each architecture. */ + +/* We just get all the registers, so we don't use regno. */ +/* ARGSUSED */ +static void +get_kcore_registers (regno) + int regno; +{ + struct user *uaddr; + + /* find the pcb for the current process */ + if (kvread (&cur_proc->p_addr, &uaddr)) + error ("cannot read u area ptr for proc at %#x", cur_proc); + if (read_pcb (core_kd, (CORE_ADDR)&uaddr->u_pcb) < 0) + error ("cannot read pcb at %#x", &uaddr->u_pcb); +} + +static void +kcore_files_info (t) + struct target_ops *t; +{ + printf ("\t`%s'\n", core_file); +} + +static int +kcore_xfer_kmem (memaddr, myaddr, len, write, target) + CORE_ADDR memaddr; + char *myaddr; + int len; + int write; + struct target_ops *target; +{ + int n; + + if (!memaddr) + return (0); + + if (memaddr < kernel_start) + return xfer_umem (memaddr, myaddr, len, write); + + n = write ? + kvm_write (core_kd, memaddr, myaddr, len) : + kvm_read (core_kd, memaddr, myaddr, len) ; + + if (n < 0) + return 0; + return n; +} + +static int +xfer_umem (memaddr, myaddr, len, write) + CORE_ADDR memaddr; + char *myaddr; + int len; + int write; /* ignored */ +{ + int n; + struct proc proc; + + if (kvread (cur_proc, &proc)) + error ("cannot read proc at %#x", cur_proc); + n = kvm_uread (core_kd, &proc, memaddr, myaddr, len) ; + + if (n < 0) + return 0; + return n; +} + +static void +set_proc_cmd (arg, from_tty) + char *arg; + int from_tty; +{ + CORE_ADDR paddr; + struct kinfo_proc *kp; + int cnt = 0; + + if (!arg) + error_no_arg ("proc address for new current process"); + if (!kernel_debugging) + error ("not debugging kernel"); + + paddr = (CORE_ADDR)parse_and_eval_address (arg); + /* assume it's a proc pointer if it's in the kernel */ + if (paddr >= kernel_start) { + if (set_proc_context(paddr)) + error("invalid proc address"); + } else { + kp = kvm_getprocs(core_kd, KERN_PROC_PID, paddr, &cnt); + if (!cnt) + error("invalid pid"); + if (set_proc_context((CORE_ADDR)kp->kp_eproc.e_paddr)) + error("invalid proc address"); + } +} + + + +#define KERNOFF ((unsigned)KERNBASE) +#define INKERNEL(x) ((x) >= KERNOFF) + +static CORE_ADDR sbr; +static CORE_ADDR curpcb; +static CORE_ADDR kstack; +static int found_pcb; +static int devmem; +static int kfd; +static struct pcb pcb; + +/* substitutes for the stuff in libkvm which doesn't work */ +/* most of this was taken from the old kgdb */ + +/* we don't need all this stuff, but the call should look the same */ + +static int +kvm_open (efile, cfile, sfile, perm, errout) + const char *efile; + char *cfile; + char *sfile; /* makes this kvm_open more compatible to the one in libkvm */ + int perm; + char *errout; /* makes this kvm_open more compatible to the one in libkvm */ +{ + struct stat stb; + CORE_ADDR addr; + int cfd; + + if ((cfd = open (cfile, perm, 0)) < 0) + return (cfd); + + fstat (cfd, &stb); + if ((stb.st_mode & S_IFMT) == S_IFCHR + && stb.st_rdev == makedev (2, 0)) + { + devmem = 1; + kfd = open ("/dev/kmem", perm, 0); + } + + physrd (cfd, ksym_lookup ("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr); + printf ("IdlePTD %x\n", sbr); + curpcb = ksym_lookup ("curpcb") - KERNOFF; + physrd (cfd, curpcb, (char*)&curpcb, sizeof curpcb); + kstack = ksym_lookup ("kstack"); + + found_pcb = 1; /* for vtophys */ + if (!devmem) + read_pcb (cfd, ksym_lookup ("dumppcb") - KERNOFF); + else + read_pcb (cfd, kvtophys (cfd, kstack)); + + return (cfd); +} + +static int +kvm_close (fd) + int fd; +{ + return (close (fd)); +} + +static int +kvm_write (core_kd, memaddr, myaddr, len) + int core_kd; + CORE_ADDR memaddr; + char *myaddr; +{ + int cc; + + if (devmem) + { + if (kfd > 0) + { + /* + * Just like kvm_read, only we write. + */ + errno = 0; + if (lseek (kfd, (off_t)memaddr, 0) < 0 + && errno != 0) + { + error ("kvm_write:invalid address (%x)", memaddr); + return (0); + } + cc = write (kfd, myaddr, len); + if (cc < 0) + { + error ("kvm_write:write failed"); + return (0); + } + else if (cc < len) + error ("kvm_write:short write"); + return (cc); + } + else + return (0); + } + else + { + printf ("kvm_write not implemented for dead kernels\n"); + return (0); + } + /* NOTREACHED */ +} + +static int +kvm_read (core_kd, memaddr, myaddr, len) + int core_kd; + CORE_ADDR memaddr; + char *myaddr; +{ + return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); +} + +static int +kvm_uread (core_kd, p, memaddr, myaddr, len) + int core_kd; + register struct proc *p; + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register char *cp; + char procfile[MAXPATHLEN]; + ssize_t amount; + int fd; + + if (devmem) + { + cp = myaddr; + + sprintf (procfile, "/proc/%d/mem", p->p_pid); + fd = open (procfile, O_RDONLY, 0); + + if (fd < 0) + { + error ("cannot open %s", procfile); + close (fd); + return (0); + } + + while (len > 0) + { + if (lseek (fd, memaddr, 0) == -1 && errno != 0) + { + error ("invalid address (%x) in %s", + memaddr, procfile); + break; + } + amount = read (fd, cp, len); + if (amount < 0) + { + error ("error reading %s", procfile); + break; + } + cp += amount; + memaddr += amount; + len -= amount; + } + + close (fd); + return (ssize_t) (cp - myaddr); + } + else + return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); +} + +static struct kinfo_proc kp; + +/* + * try to do what kvm_proclist in libkvm would do + */ +static int +kvm_proclist (cfd, pid, p, cnt) +int cfd, pid, *cnt; +struct proc *p; +{ + struct proc lp; + + for (; p != NULL; p = lp.p_list.le_next) { + if (!kvm_read(cfd, (CORE_ADDR)p, (char *)&lp, sizeof (lp))) + return (0); + if (lp.p_pid != pid) + continue; + kp.kp_eproc.e_paddr = p; + *cnt = 1; + return (1); + } + *cnt = 0; + return (0); +} + +/* + * try to do what kvm_deadprocs in libkvm would do + */ +static struct kinfo_proc * +kvm_deadprocs (cfd, pid, cnt) +int cfd, pid, *cnt; +{ + CORE_ADDR allproc, zombproc; + struct proc *p; + + allproc = ksym_lookup("allproc"); + if (kvm_read(cfd, allproc, (char *)&p, sizeof (p)) == 0) + return (NULL); + kvm_proclist (cfd, pid, p, cnt); + if (!*cnt) { + zombproc = ksym_lookup("zombproc"); + if (kvm_read(cfd, zombproc, (char *)&p, sizeof (p)) == 0) + return (NULL); + kvm_proclist (cfd, pid, p, cnt); + } + return (&kp); +} + +/* + * try to do what kvm_getprocs in libkvm would do + */ +static struct kinfo_proc * +kvm_getprocs (cfd, op, proc, cnt) +int cfd, op, *cnt; +CORE_ADDR proc; +{ + int mib[4], size; + + *cnt = 0; + /* assume it's a pid */ + if (devmem) { /* "live" kernel, use sysctl */ + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = (int)proc; + size = sizeof (kp); + if (sysctl (mib, 4, &kp, &size, NULL, 0) < 0) { + perror("sysctl"); + *cnt = 0; + return (NULL); + } + if (!size) + *cnt = 0; + else + *cnt = 1; + return (&kp); + } else + return (kvm_deadprocs (cfd, (int)proc, cnt)); +} + +static int +physrd (cfd, addr, dat, len) + int cfd; + u_int addr; + char *dat; + int len; +{ + if (lseek (cfd, (off_t)addr, L_SET) == -1) + return (-1); + return (read (cfd, dat, len)); +} + +static CORE_ADDR +kvtophys (fd, addr) + int fd; + CORE_ADDR addr; +{ + CORE_ADDR v; + unsigned int pte; + static CORE_ADDR PTD = -1; + CORE_ADDR current_ptd; + + /* + * If we're looking at the kernel stack, + * munge the address to refer to the user space mapping instead; + * that way we get the requested process's kstack, not the running one. + */ + /* + * this breaks xlating user addresses from a crash dump so only + * do it for a "live" kernel. + */ + if (devmem && addr >= kstack && addr < kstack + ctob (UPAGES)) + addr = (addr - kstack) + curpcb; + + /* + * We may no longer have a linear system page table... + * + * Here's the scoop. IdlePTD contains the physical address + * of a page table directory that always maps the kernel. + * IdlePTD is in memory that is mapped 1-to-1, so we can + * find it easily given its 'virtual' address from ksym_lookup(). + * For hysterical reasons, the value of IdlePTD is stored in sbr. + * + * To look up a kernel address, we first convert it to a 1st-level + * address and look it up in IdlePTD. This gives us the physical + * address of a page table page; we extract the 2nd-level part of + * VA and read the 2nd-level pte. Finally, we add the offset part + * of the VA into the physical address from the pte and return it. + * + * User addresses are a little more complicated. If we don't have + * a current PCB from read_pcb(), we use PTD, which is the (fixed) + * virtual address of the current ptd. Since it's NOT in 1-to-1 + * kernel space, we must look it up using IdlePTD. If we do have + * a pcb, we get the ptd from pcb_ptd. + */ + + if (INKERNEL (addr)) + current_ptd = sbr; + else if (found_pcb == 0) + { + if (PTD == -1) + PTD = kvtophys (fd, ksym_lookup ("PTD")); + current_ptd = PTD; + } + else + current_ptd = pcb.pcb_cr3; + + /* + * Read the first-level page table (ptd). + */ + v = current_ptd + ( (unsigned)addr >> PDRSHIFT) * sizeof pte; + if (physrd (fd, v, (char *)&pte, sizeof pte) < 0 || (pte&PG_V) == 0) + return (~0); + + /* + * Read the second-level page table. + */ + v = (pte&PG_FRAME) + ((addr >> PAGE_SHIFT)&(NPTEPG-1)) * sizeof pte; + if (physrd (fd, v, (char *) &pte, sizeof (pte)) < 0 || (pte&PG_V) == 0) + return (~0); + + addr = (pte & PG_FRAME) + (addr & PAGE_MASK); +#if 0 + printf ("vtophys (%x) -> %x\n", oldaddr, addr); +#endif + return (addr); +} + +static int +read_pcb (fd, uaddr) + int fd; + CORE_ADDR uaddr; +{ + int i; + int *pcb_regs = (int *)&pcb; + int eip; + CORE_ADDR nuaddr = uaddr; + + /* need this for the `proc' command to work */ + if (INKERNEL(uaddr)) + nuaddr = kvtophys(fd, uaddr); + + if (physrd (fd, nuaddr, (char *)&pcb, sizeof pcb) < 0) + { + error ("cannot read pcb at %x\n", uaddr); + return (-1); + } + printf ("current pcb at %x\n", uaddr); + + /* + * get the register values out of the sys pcb and + * store them where `read_register' will find them. + */ + for (i = 0; i < 8; ++i) + supply_register (i, (char *)&pcb_regs[i+10]); + supply_register (8, (char *)&pcb_regs[8]); /* eip */ + supply_register (9, (char *)&pcb_regs[9]); /* eflags */ + for (i = 10; i < 13; ++i) /* cs, ss, ds */ + supply_register (i, (char *)&pcb_regs[i+9]); + supply_register (13, (char *)&pcb_regs[18]); /* es */ + for (i = 14; i < 16; ++i) /* fs, gs */ + supply_register (i, (char *)&pcb_regs[i+8]); + +#if 0 /* doesn't work ??? */ + /* Hmm... */ + if (target_read_memory (pcb_regs[5+10]+4, &eip, sizeof eip, 0)) + error ("Cannot read PC."); + supply_register (8, (char *)&eip); /* eip */ +#endif + + /* XXX 80387 registers? */ +} + +/* + * read len bytes from kernel virtual address 'addr' into local + * buffer 'buf'. Return numbert of bytes if read ok, 0 otherwise. On read + * errors, portion of buffer not read is zeroed. + */ + +static int +kernel_core_file_hook (fd, addr, buf, len) + int fd; + CORE_ADDR addr; + char *buf; + int len; +{ + int i; + CORE_ADDR paddr; + register char *cp; + int cc; + + cp = buf; + + while (len > 0) + { + paddr = kvtophys (fd, addr); + if (paddr == ~0) + { + memset (buf, '\000', len); + break; + } + /* we can't read across a page boundary */ + i = min (len, PAGE_SIZE - (addr & PAGE_MASK)); + if ( (cc = physrd (fd, paddr, cp, i)) <= 0) + { + memset (cp, '\000', len); + return (cp - buf); + } + cp += cc; + addr += cc; + len -= cc; + } + return (cp - buf); +} + +struct target_ops kcore_ops = { + "kcore", /* to_shortname */ + "Kernel core dump file", /* to_longname */ + "Use a core file as a target. Specify the filename of the core file.", /* to_doc */ + kcore_open, /* to_open */ + kcore_close, /* to_close */ + find_default_attach, /* to_attach */ + kcore_detach, /* to_detach */ + NULL, /* to_resume */ + NULL, /* to_wait */ + get_kcore_registers, /* to_fetch_registers */ + NULL, /* to_store_registers */ + NULL, /* to_prepare_to_store */ + kcore_xfer_kmem, /* to_xfer_memory */ + kcore_files_info, /* 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 */ + NULL, /* to_kill */ + NULL, /* to_load */ + NULL, /* to_lookup_symbol */ + find_default_create_inferior, /* to_create_inferior */ + NULL, /* to_mourn_inferior */ + 0, /* to_can_run */ + 0, /* to_notice_signals */ + NULL, /* to_thread_alive */ + 0, /* to_stop */ + kcore_stratum, /* to_stratum */ + NULL, /* to_next */ + 0, /* 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 */ +}; + +void +_initialize_kcorelow() +{ + add_target (&kcore_ops); + add_com ("proc", class_obscure, set_proc_cmd, "Set current process context"); +} diff --git a/gnu/usr.bin/gdb/gdb/COPYING b/gnu/usr.bin/gdb/gdb/COPYING deleted file mode 100644 index a43ea21..0000000 --- a/gnu/usr.bin/gdb/gdb/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: 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 -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - 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. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/gnu/usr.bin/gdb/gdb/Makefile b/gnu/usr.bin/gdb/gdb/Makefile index 47ad0db..981ac45 100644 --- a/gnu/usr.bin/gdb/gdb/Makefile +++ b/gnu/usr.bin/gdb/gdb/Makefile @@ -1,16 +1,20 @@ # $FreeBSD$ PROG = gdb + +GDBDIR= ${.CURDIR}/../../../../contrib/gdb +.PATH: ${GDBDIR}/gdb +.PATH: ${GDBDIR}/opcodes + BINDIR= /usr/bin -CLEANFILES+= y.tab.h c-exp.tab.c ch-exp.tab.c m2-exp.tab.c SRCS = annotate.c blockframe.c breakpoint.c buildsym.c c-lang.c \ c-typeprint.c c-valprint.c ch-lang.c ch-typeprint.c \ - ch-valprint.c coffread.c command.c complaints.c copying.c core.c \ - coredep.c corelow.c cp-valprint.c \ - dcache.c dbxread.c demangle.c disassemble.c dis-buf.c dwarfread.c \ + ch-valprint.c coffread.c command.c complaints.c copying.c core-aout.c \ + corelow.c cp-valprint.c \ + dcache.c dbxread.c demangle.c dwarfread.c \ elfread.c environ.c eval.c exec.c expprint.c \ - findvar.c fork-child.c freebsd-nat.c gdbtypes.c i386-dis.c \ - i386-pinsn.c i386-tdep.c infcmd.c inflow.c infptrace.c \ + findvar.c fork-child.c i386b-nat.c gdbtypes.c \ + i386-tdep.c infcmd.c inflow.c infptrace.c \ infrun.c inftarg.c init.c kcorelow.c language.c \ m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \ mem-break.c minsyms.c objfiles.c parse.c \ @@ -19,36 +23,29 @@ SRCS = annotate.c blockframe.c breakpoint.c buildsym.c c-lang.c \ symtab.c target.c thread.c top.c \ typeprint.c utils.c valarith.c valops.c \ valprint.c values.c version.c serial.c ser-unix.c mdebugread.c\ - c-exp.tab.c ch-exp.tab.c m2-exp.tab.c compat_que.c - -c-exp.tab.c: $(.CURDIR)/c-exp.y - yacc -d -p c_ $(.CURDIR)/c-exp.y - sed -e '/extern.*malloc/d' -e '/extern.*realloc/d' -e '/extern.*free/d' \ - -e '/include.*malloc.h/d' -e 's/malloc/xmalloc/g' \ - -e 's/realloc/xrealloc/g' < y.tab.c > c-exp.new - rm -f y.tab.c - mv -f c-exp.new ./c-exp.tab.c + c-exp.tab.c f-exp.tab.c m2-exp.tab.c i387-tdep.c \ + kvm-fbsd.c bcache.c \ + corefile.c ch-exp.c f-lang.c scm-exp.c scm-lang.c \ + scm-valprint.c f-typeprint.c f-valprint.c nlmread.c \ + callback.c +SRCS+= i386-dis.c dis-buf.c disassemble.c -ch-exp.tab.c: $(.CURDIR)/ch-exp.y - yacc -d -p ch_ $(.CURDIR)/ch-exp.y - sed -e '/extern.*malloc/d' -e '/extern.*realloc/d' -e '/extern.*free/d' \ - -e '/include.*malloc.h/d' -e 's/malloc/xmalloc/g' \ - -e 's/realloc/xrealloc/g' < y.tab.c > ch-exp.new - rm -f y.tab.c - mv -f ch-exp.new ./ch-exp.tab.c - -m2-exp.tab.c: $(.CURDIR)/m2-exp.y - yacc -d -p m2_ $(.CURDIR)/m2-exp.y - sed -e '/extern.*malloc/d' -e '/extern.*realloc/d' -e '/extern.*free/d' \ - -e '/include.*malloc.h/d' -e 's/malloc/xmalloc/g' \ - -e 's/realloc/xrealloc/g' < y.tab.c > m2-exp.new - rm -f y.tab.c - mv -f m2-exp.new ./m2-exp.tab.c +CFLAGS+= -I$(.CURDIR) -I${DESTDIR}/usr/include/readline -I$(.CURDIR)/../bfd +# use phkmalloc +CFLAGS+= -DNO_MMALLOC +# uncomment the next line if you want to debug gdb +#CFLAGS+= -g +.if exists(${.OBJDIR}/../bfd) +LDADD+= -L${.OBJDIR}/../bfd -lbfd +DPADD+= ${.OBJDIR}/../bfd/libbfd.a +.else +LDADD+= -L${.CURDIR}/../bfd/ -lbfd +DPADD+= ${.CURDIR}/../bfd/libbfd.a +.endif -CFLAGS+= -I$(.CURDIR)/. -I${DESTDIR}/usr/include/readline -I$(.CURDIR)/../bfd -DPADD+= ${LIBREADLINE} ${LIBTERMCAP} ${LIBGNUREGEX} -LDADD+= -lreadline -ltermcap -lgnuregex +DPADD+= ${LIBREADLINE} ${LIBGNUREGEX} +LDADD+= -lreadline -lgnuregex .if exists(${.OBJDIR}/../libiberty) LDADD+= -L${.OBJDIR}/../libiberty -liberty @@ -58,20 +55,15 @@ LDADD+= -L${.CURDIR}/../libiberty/ -liberty DPADD+= ${.CURDIR}/../libiberty/libiberty.a .endif -.if exists(${.OBJDIR}/../bfd) -LDADD+= -L${.OBJDIR}/../bfd -lbfd -DPADD+= ${.OBJDIR}/../bfd/libbfd.a -.else -LDADD+= -L${.CURDIR}/../bfd/ -lbfd -DPADD+= ${.CURDIR}/../bfd/libbfd.a -.endif +DPADD+= ${LIBTERMCAP} +LDADD+= -ltermcap -lmalloc -.if exists(${.OBJDIR}/../mmalloc) -LDADD+= -L${.OBJDIR}/../mmalloc -lmmalloc -DPADD+= ${.OBJDIR}/../mmalloc/libmmalloc.a +.if exists(${.OBJDIR}/../libiberty) +LDADD+= -L${.OBJDIR}/../libiberty -liberty +DPADD+= ${.OBJDIR}/../libiberty/libiberty.a .else -LDADD+= -L${.CURDIR}/../mmalloc/ -lmmalloc -DPADD+= ${.CURDIR}/../mmalloc/libmmalloc.a +LDADD+= -L${.CURDIR}/../libiberty/ -liberty +DPADD+= ${.CURDIR}/../libiberty/libiberty.a .endif .include diff --git a/gnu/usr.bin/gdb/gdb/annotate.c b/gnu/usr.bin/gdb/gdb/annotate.c deleted file mode 100644 index 0a73fb5..0000000 --- a/gnu/usr.bin/gdb/gdb/annotate.c +++ /dev/null @@ -1,521 +0,0 @@ -/* Annotation routines for GDB. - Copyright 1986, 1989, 1990, 1991, 1992 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 "defs.h" -#include "annotate.h" -#include "value.h" -#include "target.h" -#include "gdbtypes.h" - -static void print_value_flags PARAMS ((struct type *)); - -static void -print_value_flags (t) - struct type *t; -{ - if (can_dereference (t)) - printf_filtered ("*"); - else - printf_filtered ("-"); -} - -void -breakpoints_changed () -{ - if (annotation_level > 1) - { - target_terminal_ours (); - printf_unfiltered ("\n\032\032breakpoints-invalid\n"); - } -} - -void -annotate_breakpoint (num) - int num; -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032breakpoint %d\n", num); -} - -void -annotate_watchpoint (num) - int num; -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032watchpoint %d\n", num); -} - -void -annotate_starting () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032starting\n"); -} - -void -annotate_stopped () -{ - 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); -} - -void -annotate_signalled () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032signalled\n"); -} - -void -annotate_signal_name () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032signal-name\n"); -} - -void -annotate_signal_name_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032signal-name-end\n"); -} - -void -annotate_signal_string () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032signal-string\n"); -} - -void -annotate_signal_string_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032signal-string-end\n"); -} - -void -annotate_signal () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032signal\n"); -} - -void -annotate_breakpoints_headers () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032breakpoints-headers\n"); -} - -void -annotate_field (num) - int num; -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032field %d\n", num); -} - -void -annotate_breakpoints_table () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032breakpoints-table\n"); -} - -void -annotate_record () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032record\n"); -} - -void -annotate_breakpoints_table_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032breakpoints-table-end\n"); -} - -void -annotate_frames_invalid () -{ - if (annotation_level > 1) - { - target_terminal_ours (); - printf_unfiltered ("\n\032\032frames-invalid\n"); - } -} - -void -annotate_field_begin (type) - struct type *type; -{ - if (annotation_level > 1) - { - printf_filtered ("\n\032\032field-begin "); - print_value_flags (type); - printf_filtered ("\n"); - } -} - -void -annotate_field_name_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032field-name-end\n"); -} - -void -annotate_field_value () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032field-value\n"); -} - -void -annotate_field_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032field-end\n"); -} - -void -annotate_quit () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032quit\n"); -} - -void -annotate_error () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032error\n"); -} - -void -annotate_error_begin () -{ - if (annotation_level > 1) - fprintf_filtered (gdb_stderr, "\n\032\032error-begin\n"); -} - -void -annotate_value_history_begin (histindex, type) - int histindex; - struct type *type; -{ - if (annotation_level > 1) - { - printf_filtered ("\n\032\032value-history-begin %d ", histindex); - print_value_flags (type); - printf_filtered ("\n"); - } -} - -void -annotate_value_begin (type) - struct type *type; -{ - if (annotation_level > 1) - { - printf_filtered ("\n\032\032value-begin "); - print_value_flags (type); - printf_filtered ("\n"); - } -} - -void -annotate_value_history_value () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032value-history-value\n"); -} - -void -annotate_value_history_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032value-history-end\n"); -} - -void -annotate_value_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032value-end\n"); -} - -void -annotate_display_begin () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032display-begin\n"); -} - -void -annotate_display_number_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032display-number-end\n"); -} - -void -annotate_display_format () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032display-format\n"); -} - -void -annotate_display_expression () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032display-expression\n"); -} - -void -annotate_display_expression_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032display-expression-end\n"); -} - -void -annotate_display_value () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032display-value\n"); -} - -void -annotate_display_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032display-end\n"); -} - -void -annotate_arg_begin () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032arg-begin\n"); -} - -void -annotate_arg_name_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032arg-name-end\n"); -} - -void -annotate_arg_value (type) - struct type *type; -{ - if (annotation_level > 1) - { - printf_filtered ("\n\032\032arg-value "); - print_value_flags (type); - printf_filtered ("\n"); - } -} - -void -annotate_arg_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032arg-end\n"); -} - -void -annotate_source (filename, line, character, mid, pc) - char *filename; - int line; - int character; - int mid; - CORE_ADDR pc; -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032source "); - else - printf_filtered ("\032\032"); - - printf_filtered ("%s:%d:%d:%s:", filename, - line, character, - mid ? "middle" : "beg"); - print_address_numeric (pc, 0, gdb_stdout); - printf_filtered ("\n"); -} - -void -annotate_frame_begin (level, pc) - int level; - CORE_ADDR pc; -{ - if (annotation_level > 1) - { - printf_filtered ("\n\032\032frame-begin %d ", level); - print_address_numeric (pc, 0, gdb_stdout); - printf_filtered ("\n"); - } -} - -void -annotate_function_call () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032function-call\n"); -} - -void -annotate_signal_handler_caller () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032signal-handler-caller\n"); -} - -void -annotate_frame_address () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-address\n"); -} - -void -annotate_frame_address_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-address-end\n"); -} - -void -annotate_frame_function_name () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-function-name\n"); -} - -void -annotate_frame_args () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-args\n"); -} - -void -annotate_frame_source_begin () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-source-begin\n"); -} - -void -annotate_frame_source_file () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-source-file\n"); -} - -void -annotate_frame_source_file_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-source-file-end\n"); -} - -void -annotate_frame_source_line () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-source-line\n"); -} - -void -annotate_frame_source_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-source-end\n"); -} - -void -annotate_frame_where () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-where\n"); -} - -void -annotate_frame_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032frame-end\n"); -} - -void -annotate_array_section_begin (index, elttype) - int index; - struct type *elttype; -{ - if (annotation_level > 1) - { - printf_filtered ("\n\032\032array-section-begin %d ", index); - print_value_flags (elttype); - printf_filtered ("\n"); - } -} - -void -annotate_elt_rep (repcount) - unsigned int repcount; -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032elt-rep %u\n", repcount); -} - -void -annotate_elt_rep_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032elt-rep-end\n"); -} - -void -annotate_elt () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032elt\n"); -} - -void -annotate_array_section_end () -{ - if (annotation_level > 1) - printf_filtered ("\n\032\032array-section-end\n"); -} - diff --git a/gnu/usr.bin/gdb/gdb/annotate.h b/gnu/usr.bin/gdb/gdb/annotate.h deleted file mode 100644 index 0ec9765..0000000 --- a/gnu/usr.bin/gdb/gdb/annotate.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Annotation routines for GDB. - Copyright 1986, 1989, 1990, 1991, 1992 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. */ - -extern void breakpoints_changed PARAMS ((void)); - -extern void annotate_breakpoint PARAMS ((int)); -extern void annotate_watchpoint PARAMS ((int)); -extern void annotate_starting PARAMS ((void)); -extern void annotate_stopped PARAMS ((void)); -extern void annotate_exited PARAMS ((int)); -extern void annotate_signalled PARAMS ((void)); -extern void annotate_signal_name PARAMS ((void)); -extern void annotate_signal_name_end PARAMS ((void)); -extern void annotate_signal_string PARAMS ((void)); -extern void annotate_signal_string_end PARAMS ((void)); -extern void annotate_signal PARAMS ((void)); - -extern void annotate_breakpoints_headers PARAMS ((void)); -extern void annotate_field PARAMS ((int)); -extern void annotate_breakpoints_table PARAMS ((void)); -extern void annotate_record PARAMS ((void)); -extern void annotate_breakpoints_table_end PARAMS ((void)); - -extern void annotate_frames_invalid PARAMS ((void)); - -#ifdef __STDC__ -struct type; -#endif - -extern void annotate_field_begin PARAMS ((struct type *)); -extern void annotate_field_name_end PARAMS ((void)); -extern void annotate_field_value PARAMS ((void)); -extern void annotate_field_end PARAMS ((void)); - -extern void annotate_quit PARAMS ((void)); -extern void annotate_error PARAMS ((void)); -extern void annotate_error_begin PARAMS ((void)); - -extern void annotate_value_history_begin PARAMS ((int, struct type *)); -extern void annotate_value_begin PARAMS ((struct type *)); -extern void annotate_value_history_value PARAMS ((void)); -extern void annotate_value_history_end PARAMS ((void)); -extern void annotate_value_end PARAMS ((void)); - -extern void annotate_display_begin PARAMS ((void)); -extern void annotate_display_number_end PARAMS ((void)); -extern void annotate_display_format PARAMS ((void)); -extern void annotate_display_expression PARAMS ((void)); -extern void annotate_display_expression_end PARAMS ((void)); -extern void annotate_display_value PARAMS ((void)); -extern void annotate_display_end PARAMS ((void)); - -extern void annotate_arg_begin PARAMS ((void)); -extern void annotate_arg_name_end PARAMS ((void)); -extern void annotate_arg_value PARAMS ((struct type *)); -extern void annotate_arg_end PARAMS ((void)); - -extern void annotate_source PARAMS ((char *, int, int, int, CORE_ADDR)); - -extern void annotate_frame_begin PARAMS ((int, CORE_ADDR)); -extern void annotate_function_call PARAMS ((void)); -extern void annotate_signal_handler_caller PARAMS ((void)); -extern void annotate_frame_address PARAMS ((void)); -extern void annotate_frame_address_end PARAMS ((void)); -extern void annotate_frame_function_name PARAMS ((void)); -extern void annotate_frame_args PARAMS ((void)); -extern void annotate_frame_source_begin PARAMS ((void)); -extern void annotate_frame_source_file PARAMS ((void)); -extern void annotate_frame_source_file_end PARAMS ((void)); -extern void annotate_frame_source_line PARAMS ((void)); -extern void annotate_frame_source_end PARAMS ((void)); -extern void annotate_frame_where PARAMS ((void)); -extern void annotate_frame_end PARAMS ((void)); - -extern void annotate_array_section_begin PARAMS ((int, struct type *)); -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)); diff --git a/gnu/usr.bin/gdb/gdb/ansidecl.h b/gnu/usr.bin/gdb/gdb/ansidecl.h deleted file mode 100644 index 3c0dcb3..0000000 --- a/gnu/usr.bin/gdb/gdb/ansidecl.h +++ /dev/null @@ -1,141 +0,0 @@ -/* ANSI and traditional C compatability macros - Copyright 1991, 1992 Free Software Foundation, Inc. - This file is part of the GNU C Library. - -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. */ - -/* ANSI and traditional C compatibility macros - - ANSI C is assumed if __STDC__ is #defined. - - Macro ANSI C definition Traditional C definition - ----- ---- - ---------- ----------- - ---------- - PTR `void *' `char *' - LONG_DOUBLE `long double' `double' - VOLATILE `volatile' `' - SIGNED `signed' `' - PTRCONST `void *const' `char *' - ANSI_PROTOTYPES 1 not defined - - CONST is also defined, but is obsolete. Just use const. - - DEFUN (name, arglist, args) - - Defines function NAME. - - ARGLIST lists the arguments, separated by commas and enclosed in - parentheses. ARGLIST becomes the argument list in traditional C. - - ARGS list the arguments with their types. It becomes a prototype in - ANSI C, and the type declarations in traditional C. Arguments should - be separated with `AND'. For functions with a variable number of - arguments, the last thing listed should be `DOTS'. - - DEFUN_VOID (name) - - Defines a function NAME, which takes no arguments. - - obsolete -- EXFUN (name, (prototype)) -- obsolete. - - Replaced by PARAMS. Do not use; will disappear someday soon. - Was used in external function declarations. - In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in - parentheses). In traditional C it is `NAME()'. - For a function that takes no arguments, PROTOTYPE should be `(void)'. - - PARAMS ((args)) - - We could use the EXFUN macro to handle prototype declarations, but - the name is misleading and the result is ugly. So we just define a - simple macro to handle the parameter lists, as in: - - static int foo PARAMS ((int, char)); - - This produces: `static int foo();' or `static int foo (int, char);' - - EXFUN would have done it like this: - - static int EXFUN (foo, (int, char)); - - but the function is not external...and it's hard to visually parse - the function name out of the mess. EXFUN should be considered - obsolete; new code should be written to use PARAMS. - - For example: - extern int printf PARAMS ((CONST char *format DOTS)); - int DEFUN(fprintf, (stream, format), - FILE *stream AND CONST char *format DOTS) { ... } - void DEFUN_VOID(abort) { ... } -*/ - -#ifndef _ANSIDECL_H - -#define _ANSIDECL_H 1 - - -/* Every source file includes this file, - so they will all get the switch for lint. */ -/* LINTLIBRARY */ - - -#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) -/* All known AIX compilers implement these things (but don't always - define __STDC__). The RISC/OS MIPS compiler defines these things - in SVR4 mode, but does not define __STDC__. */ - -#define PTR void * -#define PTRCONST void *CONST -#define LONG_DOUBLE long double - -#define AND , -#define NOARGS void -#define CONST const -#define VOLATILE volatile -#define SIGNED signed -#define DOTS , ... - -#define EXFUN(name, proto) name proto -#define DEFUN(name, arglist, args) name(args) -#define DEFUN_VOID(name) name(void) - -#define PROTO(type, name, arglist) type name arglist -#define PARAMS(paramlist) paramlist -#define ANSI_PROTOTYPES 1 - -#else /* Not ANSI C. */ - -#define PTR char * -#define PTRCONST PTR -#define LONG_DOUBLE double - -#define AND ; -#define NOARGS -#define CONST -#ifndef const /* some systems define it in header files for non-ansi mode */ -#define const -#endif -#define VOLATILE -#define SIGNED -#define DOTS - -#define EXFUN(name, proto) name() -#define DEFUN(name, arglist, args) name arglist args; -#define DEFUN_VOID(name) name() -#define PROTO(type, name, arglist) type name () -#define PARAMS(paramlist) () - -#endif /* ANSI C. */ - -#endif /* ansidecl.h */ diff --git a/gnu/usr.bin/gdb/gdb/bfdlink.h b/gnu/usr.bin/gdb/gdb/bfdlink.h deleted file mode 100644 index b46eb34..0000000 --- a/gnu/usr.bin/gdb/gdb/bfdlink.h +++ /dev/null @@ -1,411 +0,0 @@ -/* bfdlink.h -- header file for BFD link routines - Copyright 1993 Free Software Foundation, Inc. - Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -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. */ - -#ifndef BFDLINK_H -#define BFDLINK_H - -/* Which symbols to strip during a link. */ -enum bfd_link_strip -{ - strip_none, /* Don't strip any symbols. */ - strip_debugger, /* Strip debugging symbols. */ - strip_some, /* keep_hash is the list of symbols to keep. */ - strip_all /* Strip all symbols. */ -}; - -/* Which local symbols to discard during a link. This is irrelevant - if strip_all is used. */ -enum bfd_link_discard -{ - discard_none, /* Don't discard any locals. */ - discard_l, /* Discard locals with a certain prefix. */ - discard_all /* Discard all locals. */ -}; - -/* These are the possible types of an entry in the BFD link hash - table. */ - -enum bfd_link_hash_type -{ - bfd_link_hash_new, /* Symbol is new. */ - bfd_link_hash_undefined, /* Symbol seen before, but undefined. */ - bfd_link_hash_weak, /* Symbol is weak and undefined. */ - bfd_link_hash_defined, /* Symbol is defined. */ - bfd_link_hash_common, /* Symbol is common. */ - bfd_link_hash_indirect, /* Symbol is an indirect link. */ - bfd_link_hash_warning /* Like indirect, but warn if referenced. */ -}; - -/* The linking routines use a hash table which uses this structure for - its elements. */ - -struct bfd_link_hash_entry -{ - /* Base hash table entry structure. */ - struct bfd_hash_entry root; - /* Type of this entry. */ - enum bfd_link_hash_type type; - - /* Undefined and common symbols are kept in a linked list through - this field. This field is not in the union because that would - force us to remove entries from the list when we changed their - type, which would force the list to be doubly linked, which would - waste more memory. When an undefined or common symbol is - created, it should be added to this list, the head of which is in - the link hash table itself. As symbols are defined, they need - not be removed from the list; anything which reads the list must - doublecheck the symbol type. - - Weak symbols are not kept on this list. - - Defined symbols use this field as a reference marker. If the - field is not NULL, or this structure is the tail of the undefined - symbol list, the symbol has been referenced. If the symbol is - undefined and becomes defined, this field will automatically be - non-NULL since the symbol will have been on the undefined symbol - list. */ - struct bfd_link_hash_entry *next; - /* A union of information depending upon the type. */ - union - { - /* Nothing is kept for bfd_hash_new. */ - /* bfd_link_hash_undefined, bfd_link_hash_weak. */ - struct - { - bfd *abfd; /* BFD symbol was found in. */ - } undef; - /* bfd_link_hash_defined. */ - struct - { - bfd_vma value; /* Symbol value. */ - asection *section; /* Symbol section. */ - } def; - /* bfd_link_hash_indirect, bfd_link_hash_warning. */ - struct - { - struct bfd_link_hash_entry *link; /* Real symbol. */ - const char *warning; /* Warning (bfd_link_hash_warning only). */ - } i; - /* bfd_link_hash_common. */ - struct - { - bfd_vma size; /* Common symbol size. */ - asection *section; /* Symbol section. */ - } c; - } u; -}; - -/* This is the link hash table. It is a derived class of - bfd_hash_table. */ - -struct bfd_link_hash_table -{ - /* The hash table itself. */ - struct bfd_hash_table table; - /* The back end which created this hash table. This indicates the - type of the entries in the hash table, which is sometimes - important information when linking object files of different - types together. */ - const bfd_target *creator; - /* A linked list of undefined and common symbols, linked through the - next field in the bfd_link_hash_entry structure. */ - struct bfd_link_hash_entry *undefs; - /* Entries are added to the tail of the undefs list. */ - struct bfd_link_hash_entry *undefs_tail; -}; - -/* Look up an entry in a link hash table. If FOLLOW is true, this - follows bfd_link_hash_indirect and bfd_link_hash_warning links to - the real symbol. */ -extern struct bfd_link_hash_entry *bfd_link_hash_lookup - PARAMS ((struct bfd_link_hash_table *, const char *, boolean create, - boolean copy, boolean follow)); - -/* Traverse a link hash table. */ -extern void bfd_link_hash_traverse - PARAMS ((struct bfd_link_hash_table *, - boolean (*) (struct bfd_link_hash_entry *, PTR), - PTR)); - -/* Add an entry to the undefs list. */ -extern void bfd_link_add_undef - PARAMS ((struct bfd_link_hash_table *, struct bfd_link_hash_entry *)); - -/* This structure holds all the information needed to communicate - between BFD and the linker when doing a link. */ - -struct bfd_link_info -{ - /* Function callbacks. */ - const struct bfd_link_callbacks *callbacks; - /* true if BFD should generate a relocateable object file. */ - boolean relocateable; - /* true if BFD should generate a shared object. */ - boolean shared; - /* Which symbols to strip. */ - enum bfd_link_strip strip; - /* Which local symbols to discard. */ - enum bfd_link_discard discard; - /* The local symbol prefix to discard if using discard_l. */ - unsigned int lprefix_len; - const char *lprefix; - /* true if symbols should be retained in memory, false if they - should be freed and reread. */ - boolean keep_memory; - /* The list of input BFD's involved in the link. These are chained - together via the link_next field. */ - bfd *input_bfds; - /* If a symbol should be created for each input BFD, this is section - where those symbols should be placed. It must be a section in - the output BFD. It may be NULL, in which case no such symbols - will be created. This is to support CREATE_OBJECT_SYMBOLS in the - linker command language. */ - asection *create_object_symbols_section; - /* Hash table handled by BFD. */ - struct bfd_link_hash_table *hash; - /* Hash table of symbols to keep. This is NULL unless strip is - strip_some. */ - struct bfd_hash_table *keep_hash; - /* Hash table of symbols to report back via notice_callback. If - this is NULL no symbols are reported back. */ - struct bfd_hash_table *notice_hash; -}; - -/* This structures holds a set of callback functions. These are - called by the BFD linker routines. The first argument to each - callback function is the bfd_link_info structure being used. Each - function returns a boolean value. If the function returns false, - then the BFD function which called it will return with a failure - indication. */ - -struct bfd_link_callbacks -{ - /* A function which is called when an object is added from an - archive. ABFD is the archive element being added. NAME is the - name of the symbol which caused the archive element to be pulled - in. */ - boolean (*add_archive_element) PARAMS ((struct bfd_link_info *, - bfd *abfd, - const char *name)); - /* A function which is called when a symbol is found with multiple - definitions. NAME is the symbol which is defined multiple times. - OBFD is the old BFD, OSEC is the old section, OVAL is the old - value, NBFD is the new BFD, NSEC is the new section, and NVAL is - the new value. OBFD may be NULL. OSEC and NSEC may be - bfd_com_section or bfd_ind_section. */ - boolean (*multiple_definition) PARAMS ((struct bfd_link_info *, - const char *name, - bfd *obfd, - asection *osec, - bfd_vma oval, - bfd *nbfd, - asection *nsec, - bfd_vma nval)); - /* A function which is called when a common symbol is defined - multiple times. NAME is the symbol appearing multiple times. - OBFD is the BFD of the existing symbol. OTYPE is the type of the - existing symbol, either bfd_link_hash_defined or - bfd_link_hash_common. If OTYPE is bfd_link_hash_common, OSIZE is - the size of the existing symbol. NBFD is the BFD of the new - symbol. NTYPE is the type of the new symbol, either - bfd_link_hash_defined or bfd_link_hash_common. If NTYPE is - bfd_link_hash_common, NSIZE is the size of the new symbol. */ - boolean (*multiple_common) PARAMS ((struct bfd_link_info *, - const char *name, - bfd *obfd, - enum bfd_link_hash_type otype, - bfd_vma osize, - bfd *nbfd, - enum bfd_link_hash_type ntype, - bfd_vma nsize)); - /* A function which is called to add a symbol to a set. ENTRY is - the link hash table entry for the set itself (e.g., - __CTOR_LIST__). RELOC is the relocation to use for an entry in - the set when generating a relocateable file, and is also used to - get the size of the entry when generating an executable file. - ABFD, SEC and VALUE identify the value to add to the set. */ - boolean (*add_to_set) PARAMS ((struct bfd_link_info *, - struct bfd_link_hash_entry *entry, - bfd_reloc_code_real_type reloc, - bfd *abfd, asection *sec, bfd_vma value)); - /* A function which is called when the name of a g++ constructor or - destructor is found. This is only called by some object file - formats. CONSTRUCTOR is true for a constructor, false for a - destructor. This will use BFD_RELOC_CTOR when generating a - relocateable file. NAME is the name of the symbol found. ABFD, - SECTION and VALUE are the value of the symbol. */ - boolean (*constructor) PARAMS ((struct bfd_link_info *, - boolean constructor, - const char *name, bfd *abfd, asection *sec, - bfd_vma value)); - /* A function which is called when there is a reference to a warning - symbol. WARNING is the warning to be issued. */ - boolean (*warning) PARAMS ((struct bfd_link_info *, - const char *warning)); - /* A function which is called when a relocation is attempted against - an undefined symbol. NAME is the symbol which is undefined. - ABFD, SECTION and ADDRESS identify the location from which the - reference is made. */ - boolean (*undefined_symbol) PARAMS ((struct bfd_link_info *, - const char *name, bfd *abfd, - asection *section, bfd_vma address)); - /* A function which is called when a reloc overflow occurs. NAME is - the name of the symbol or section the reloc is against, - RELOC_NAME is the name of the relocation, and ADDEND is any - addend that is used. ABFD, SECTION and ADDRESS identify the - location at which the overflow occurs; if this is the result of a - bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then - ABFD will be NULL. */ - boolean (*reloc_overflow) PARAMS ((struct bfd_link_info *, - const char *name, - const char *reloc_name, bfd_vma addend, - bfd *abfd, asection *section, - bfd_vma address)); - /* A function which is called when a dangerous reloc is performed. - The canonical example is an a29k IHCONST reloc which does not - follow an IHIHALF reloc. MESSAGE is an appropriate message. - ABFD, SECTION and ADDRESS identify the location at which the - problem occurred; if this is the result of a - bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then - ABFD will be NULL. */ - boolean (*reloc_dangerous) PARAMS ((struct bfd_link_info *, - const char *message, - bfd *abfd, asection *section, - bfd_vma address)); - /* A function which is called when a reloc is found to be attached - to a symbol which is not being written out. NAME is the name of - the symbol. ABFD, SECTION and ADDRESS identify the location of - the reloc; if this is the result of a - bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then - ABFD will be NULL. */ - boolean (*unattached_reloc) PARAMS ((struct bfd_link_info *, - const char *name, - bfd *abfd, asection *section, - bfd_vma address)); - /* A function which is called when a symbol in notice_hash is - defined or referenced. NAME is the symbol. ABFD, SECTION and - ADDRESS are the value of the symbol. If SECTION is - bfd_und_section, this is a reference. */ - boolean (*notice) PARAMS ((struct bfd_link_info *, const char *name, - bfd *abfd, asection *section, bfd_vma address)); -}; - -/* The linker builds link_order structures which tell the code how to - include input data in the output file. */ - -/* These are the types of link_order structures. */ - -enum bfd_link_order_type -{ - bfd_undefined_link_order, /* Undefined. */ - bfd_indirect_link_order, /* Built from a section. */ - bfd_fill_link_order, /* Fill with a 16 bit constant. */ - bfd_data_link_order, /* Set to explicit data. */ - bfd_section_reloc_link_order, /* Relocate against a section. */ - bfd_symbol_reloc_link_order /* Relocate against a symbol. */ -}; - -/* This is the link_order structure itself. These form a chain - attached to the section whose contents they are describing. */ - -struct bfd_link_order -{ - /* Next link_order in chain. */ - struct bfd_link_order *next; - /* Type of link_order. */ - enum bfd_link_order_type type; - /* Offset within output section. */ - bfd_vma offset; - /* Size within output section. */ - bfd_size_type size; - /* Type specific information. */ - union - { - struct - { - /* Section to include. If this is used, then - section->output_section must be the section the - link_order is attached to, section->output_offset must - equal the link_order offset field, and section->_raw_size - must equal the link_order size field. Maybe these - restrictions should be relaxed someday. */ - asection *section; - } indirect; - struct - { - /* Value to fill with. */ - unsigned int value; - } fill; - struct - { - /* Data to put into file. The size field gives the number - of bytes which this field points to. */ - bfd_byte *contents; - } data; - struct - { - /* Description of reloc to generate. Used for - bfd_section_reloc_link_order and - bfd_symbol_reloc_link_order. */ - struct bfd_link_order_reloc *p; - } reloc; - } u; -}; - -/* A linker order of type bfd_section_reloc_link_order or - bfd_symbol_reloc_link_order means to create a reloc against a - section or symbol, respectively. This is used to implement -Ur to - generate relocs for the constructor tables. The - bfd_link_order_reloc structure describes the reloc that BFD should - create. It is similar to a arelent, but I didn't use arelent - because the linker does not know anything about most symbols, and - any asymbol structure it creates will be partially meaningless. - This information could logically be in the bfd_link_order struct, - but I didn't want to waste the space since these types of relocs - are relatively rare. */ - -struct bfd_link_order_reloc -{ - /* Reloc type. */ - bfd_reloc_code_real_type reloc; - - union - { - /* For type bfd_section_reloc_link_order, this is the section - the reloc should be against. This must be a section in the - output BFD, not any of the input BFDs. */ - asection *section; - /* For type bfd_symbol_reloc_link_order, this is the name of the - symbol the reloc should be against. */ - const char *name; - } u; - - /* Addend to use. The object file should contain zero. The BFD - backend is responsible for filling in the contents of the object - file correctly. For some object file formats (e.g., COFF) the - addend must be stored into in the object file, and for some - (e.g., SPARC a.out) it is kept in the reloc. */ - bfd_vma addend; -}; - -/* Allocate a new link_order for a section. */ -extern struct bfd_link_order *bfd_new_link_order PARAMS ((bfd *, asection *)); - -#endif diff --git a/gnu/usr.bin/gdb/gdb/blockframe.c b/gnu/usr.bin/gdb/gdb/blockframe.c deleted file mode 100644 index 732bbdb..0000000 --- a/gnu/usr.bin/gdb/gdb/blockframe.c +++ /dev/null @@ -1,866 +0,0 @@ -/* Get info from stack frames; - convert between frames, blocks, functions and pc values. - Copyright 1986, 1987, 1988, 1989, 1991 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 "defs.h" -#include "symtab.h" -#include "bfd.h" -#include "symfile.h" -#include "objfiles.h" -#include "frame.h" -#include "gdbcore.h" -#include "value.h" /* for read_register */ -#include "target.h" /* for target_has_stack */ -#include "inferior.h" /* for read_pc */ -#include "annotate.h" - -/* 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 - doing so is that some machines have no way of detecting bottom - of stack. - - A PC of zero is always considered to be the bottom of the stack. */ - -int -inside_entry_file (addr) - CORE_ADDR addr; -{ - if (addr == 0) - return 1; - if (symfile_objfile == 0) - return 0; -#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)) - return 0; -#endif - return (addr >= symfile_objfile -> ei.entry_file_lowpc && - addr < symfile_objfile -> ei.entry_file_highpc); -} - -/* Test a specified PC value to see if it is in the range of addresses - that correspond to the main() function. See comments above for why - we might want to do this. - - Typically called from FRAME_CHAIN_VALID. - - A PC of zero is always considered to be the bottom of the stack. */ - -int -inside_main_func (pc) -CORE_ADDR pc; -{ - if (pc == 0) - return 1; - if (symfile_objfile == 0) - return 0; - return (symfile_objfile -> ei.main_func_lowpc <= pc && - symfile_objfile -> ei.main_func_highpc > pc); -} - -/* Test a specified PC value to see if it is in the range of addresses - that correspond to the process entry point function. See comments - in objfiles.h for why we might want to do this. - - Typically called from FRAME_CHAIN_VALID. - - A PC of zero is always considered to be the bottom of the stack. */ - -int -inside_entry_func (pc) -CORE_ADDR pc; -{ - if (pc == 0) - return 1; - if (symfile_objfile == 0) - return 0; -#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 (pc, 0, 0)) - return 0; -#endif - return (symfile_objfile -> ei.entry_func_lowpc <= pc && - symfile_objfile -> ei.entry_func_highpc > pc); -} - -/* Address of innermost stack frame (contents of FP register) */ - -static FRAME current_frame; - -/* - * Cache for frame addresses already read by gdb. Valid only while - * inferior is stopped. Control variables for the frame cache should - * be local to this module. - */ -struct obstack frame_cache_obstack; - -/* Return the innermost (currently executing) stack frame. */ - -FRAME -get_current_frame () -{ - /* We assume its address is kept in a general register; - param.h says which register. */ - - return current_frame; -} - -void -set_current_frame (frame) - FRAME frame; -{ - current_frame = frame; -} - -FRAME -create_new_frame (addr, pc) - FRAME_ADDR addr; - CORE_ADDR pc; -{ - struct frame_info *fci; /* Same type as FRAME */ - char *name; - - fci = (struct frame_info *) - obstack_alloc (&frame_cache_obstack, - sizeof (struct frame_info)); - - /* Arbitrary frame */ - fci->next = (struct frame_info *) 0; - fci->prev = (struct frame_info *) 0; - fci->frame = addr; - fci->pc = pc; - find_pc_partial_function (pc, &name, (CORE_ADDR *)NULL,(CORE_ADDR *)NULL); - fci->signal_handler_caller = IN_SIGTRAMP (fci->pc, name); - -#ifdef INIT_EXTRA_FRAME_INFO - INIT_EXTRA_FRAME_INFO (0, fci); -#endif - - return fci; -} - -/* Return the frame that called FRAME. - If FRAME is the original frame (it has no caller), return 0. */ - -FRAME -get_prev_frame (frame) - FRAME frame; -{ - /* We're allowed to know that FRAME and "struct frame_info *" are - the same */ - return get_prev_frame_info (frame); -} - -/* Return the frame that FRAME calls (0 if FRAME is the innermost - frame). */ - -FRAME -get_next_frame (frame) - FRAME frame; -{ - /* We're allowed to know that FRAME and "struct frame_info *" are - the same */ - return frame->next; -} - -/* - * Flush the entire frame cache. - */ -void -flush_cached_frames () -{ - /* Since we can't really be sure what the first object allocated was */ - obstack_free (&frame_cache_obstack, 0); - obstack_init (&frame_cache_obstack); - - current_frame = (struct frame_info *) 0; /* Invalidate cache */ - annotate_frames_invalid (); -} - -/* Flush the frame cache, and start a new one if necessary. */ -void -reinit_frame_cache () -{ - flush_cached_frames (); - if (target_has_stack) - { - set_current_frame (create_new_frame (read_fp (), read_pc ())); - select_frame (get_current_frame (), 0); - } - else - { - set_current_frame (0); - select_frame ((FRAME) 0, -1); - } -} - -/* Return a structure containing various interesting information - about a specified stack frame. */ -/* How do I justify including this function? Well, the FRAME - identifier format has gone through several changes recently, and - it's not completely inconceivable that it could happen again. If - it does, have this routine around will help */ - -struct frame_info * -get_frame_info (frame) - FRAME frame; -{ - return frame; -} - -/* If a machine allows frameless functions, it should define a macro - FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) in param.h. FI is the struct - frame_info for the frame, and FRAMELESS should be set to nonzero - if it represents a frameless function invocation. */ - -/* Return nonzero if the function for this frame lacks a prologue. Many - machines can define FRAMELESS_FUNCTION_INVOCATION to just call this - function. */ - -int -frameless_look_for_prologue (frame) - FRAME frame; -{ - CORE_ADDR func_start, after_prologue; - func_start = (get_pc_function_start (frame->pc) + - FUNCTION_START_OFFSET); - if (func_start) - { - after_prologue = func_start; -#ifdef SKIP_PROLOGUE_FRAMELESS_P - /* This is faster, since only care whether there *is* a prologue, - not how long it is. */ - SKIP_PROLOGUE_FRAMELESS_P (after_prologue); -#else - SKIP_PROLOGUE (after_prologue); -#endif - return after_prologue == func_start; - } - 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 - to get a reasonable (i.e. best we can do under the - circumstances) backtrace by saying that it isn't. */ - return 0; -} - -/* Default a few macros that people seldom redefine. */ - -#if !defined (INIT_FRAME_PC) -#define INIT_FRAME_PC(fromleaf, prev) \ - prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) : \ - prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ()); -#endif - -#ifndef FRAME_CHAIN_COMBINE -#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain) -#endif - -/* Return a structure containing various interesting information - about the frame that called NEXT_FRAME. Returns NULL - if there is no such frame. */ - -struct frame_info * -get_prev_frame_info (next_frame) - FRAME next_frame; -{ - FRAME_ADDR address = 0; - struct frame_info *prev; - int fromleaf = 0; - char *name; - - /* If the requested entry is in the cache, return it. - Otherwise, figure out what the address should be for the entry - we're about to add to the cache. */ - - if (!next_frame) - { -#if 0 - /* This screws value_of_variable, which just wants a nice clean - NULL return from block_innermost_frame if there are no frames. - I don't think I've ever seen this message happen otherwise. - And returning NULL here is a perfectly legitimate thing to do. */ - if (!current_frame) - { - error ("You haven't set up a process's stack to examine."); - } -#endif - - return current_frame; - } - - /* If we have the prev one, return it */ - if (next_frame->prev) - return next_frame->prev; - - /* On some machines it is possible to call a function without - setting up a stack frame for it. On these machines, we - define this macro to take two args; a frameinfo pointer - identifying a frame and a variable to set or clear if it is - or isn't leafless. */ -#ifdef FRAMELESS_FUNCTION_INVOCATION - /* Still don't want to worry about this except on the innermost - frame. This macro will set FROMLEAF if NEXT_FRAME is a - frameless function invocation. */ - if (!(next_frame->next)) - { - FRAMELESS_FUNCTION_INVOCATION (next_frame, fromleaf); - if (fromleaf) - address = next_frame->frame; - } -#endif - - if (!fromleaf) - { - /* Two macros defined in tm.h specify the machine-dependent - actions to be performed here. - First, get the frame's chain-pointer. - If that is zero, the frame is the outermost frame or a leaf - called by the outermost frame. This means that if start - calls main without a frame, we'll return 0 (which is fine - anyway). - - Nope; there's a problem. This also returns when the current - routine is a leaf of main. This is unacceptable. We move - this to after the ffi test; I'd rather have backtraces from - start go curfluy than have an abort called from main not show - main. */ - address = FRAME_CHAIN (next_frame); - if (!FRAME_CHAIN_VALID (address, next_frame)) - return 0; - address = FRAME_CHAIN_COMBINE (address, next_frame); - } - if (address == 0) - return 0; - - prev = (struct frame_info *) - obstack_alloc (&frame_cache_obstack, - sizeof (struct frame_info)); - - if (next_frame) - next_frame->prev = prev; - prev->next = next_frame; - prev->prev = (struct frame_info *) 0; - prev->frame = address; - prev->signal_handler_caller = 0; - -/* This change should not be needed, FIXME! We should - determine whether any targets *need* INIT_FRAME_PC to happen - after INIT_EXTRA_FRAME_INFO and come up with a simple way to - express what goes on here. - - INIT_EXTRA_FRAME_INFO is called from two places: create_new_frame - (where the PC is already set up) and here (where it isn't). - INIT_FRAME_PC is only called from here, always after - INIT_EXTRA_FRAME_INFO. - - The catch is the MIPS, where INIT_EXTRA_FRAME_INFO requires the PC - value (which hasn't been set yet). Some other machines appear to - require INIT_EXTRA_FRAME_INFO before they can do INIT_FRAME_PC. Phoo. - - We shouldn't need INIT_FRAME_PC_FIRST to add more complication to - an already overcomplicated part of GDB. gnu@cygnus.com, 15Sep92. - - To answer the question, yes the sparc needs INIT_FRAME_PC after - INIT_EXTRA_FRAME_INFO. Suggested scheme: - - SETUP_INNERMOST_FRAME() - Default version is just create_new_frame (read_fp ()), - read_pc ()). Machines with extra frame info would do that (or the - local equivalent) and then set the extra fields. - SETUP_ARBITRARY_FRAME(argc, argv) - Only change here is that create_new_frame would no longer init extra - frame info; SETUP_ARBITRARY_FRAME would have to do that. - INIT_PREV_FRAME(fromleaf, prev) - Replace INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC. This should - also return a flag saying whether to keep the new frame, or - whether to discard it, because on some machines (e.g. mips) it - is really awkward to have FRAME_CHAIN_VALID called *before* - INIT_EXTRA_FRAME_INFO (there is no good way to get information - deduced in FRAME_CHAIN_VALID into the extra fields of the new frame). - std_frame_pc(fromleaf, prev) - This is the default setting for INIT_PREV_FRAME. It just does what - the default INIT_FRAME_PC does. Some machines will call it from - INIT_PREV_FRAME (either at the beginning, the end, or in the middle). - Some machines won't use it. - kingdon@cygnus.com, 13Apr93, 31Jan94. */ - -#ifdef INIT_FRAME_PC_FIRST - INIT_FRAME_PC_FIRST (fromleaf, prev); -#endif - -#ifdef INIT_EXTRA_FRAME_INFO - INIT_EXTRA_FRAME_INFO(fromleaf, prev); -#endif - - /* This entry is in the frame queue now, which is good since - FRAME_SAVED_PC may use that queue to figure out its value - (see tm-sparc.h). We want the pc saved in the inferior frame. */ - INIT_FRAME_PC(fromleaf, prev); - - /* If ->frame and ->pc are unchanged, we are in the process of getting - ourselves into an infinite backtrace. Some architectures check this - in FRAME_CHAIN or thereabouts, but it seems like there is no reason - this can't be an architecture-independent check. */ - if (next_frame != NULL) - { - if (prev->frame == next_frame->frame - && prev->pc == next_frame->pc) - { - next_frame->prev = NULL; - obstack_free (&frame_cache_obstack, prev); - return NULL; - } - } - - find_pc_partial_function (prev->pc, &name, - (CORE_ADDR *)NULL,(CORE_ADDR *)NULL); - if (IN_SIGTRAMP (prev->pc, name)) - prev->signal_handler_caller = 1; - - return prev; -} - -CORE_ADDR -get_frame_pc (frame) - FRAME frame; -{ - struct frame_info *fi; - fi = get_frame_info (frame); - return fi->pc; -} - -#if defined (FRAME_FIND_SAVED_REGS) -/* Find the addresses in which registers are saved in FRAME. */ - -void -get_frame_saved_regs (frame_info_addr, saved_regs_addr) - struct frame_info *frame_info_addr; - struct frame_saved_regs *saved_regs_addr; -{ - FRAME_FIND_SAVED_REGS (frame_info_addr, *saved_regs_addr); -} -#endif - -/* Return the innermost lexical block in execution - in a specified stack frame. The frame address is assumed valid. */ - -struct block * -get_frame_block (frame) - FRAME frame; -{ - struct frame_info *fi; - CORE_ADDR pc; - - fi = get_frame_info (frame); - - pc = fi->pc; - if (fi->next != 0 && fi->next->signal_handler_caller == 0) - /* We are not in the innermost frame and we were not interrupted - by a signal. We need to subtract one to get the correct block, - in case the call instruction was the last instruction of the block. - If there are any machines on which the saved pc does not point to - after the call insn, we probably want to make fi->pc point after - the call insn anyway. */ - --pc; - return block_for_pc (pc); -} - -struct block * -get_current_block () -{ - return block_for_pc (read_pc ()); -} - -CORE_ADDR -get_pc_function_start (pc) - CORE_ADDR pc; -{ - register struct block *bl; - register struct symbol *symbol; - register struct minimal_symbol *msymbol; - CORE_ADDR fstart; - - if ((bl = block_for_pc (pc)) != NULL && - (symbol = block_function (bl)) != NULL) - { - bl = SYMBOL_BLOCK_VALUE (symbol); - fstart = BLOCK_START (bl); - } - else if ((msymbol = lookup_minimal_symbol_by_pc (pc)) != NULL) - { - fstart = SYMBOL_VALUE_ADDRESS (msymbol); - } - else - { - fstart = 0; - } - return (fstart); -} - -/* Return the symbol for the function executing in frame FRAME. */ - -struct symbol * -get_frame_function (frame) - FRAME frame; -{ - register struct block *bl = get_frame_block (frame); - if (bl == 0) - return 0; - return block_function (bl); -} - -/* Return the blockvector immediately containing the innermost lexical block - containing the specified pc value, 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) - register CORE_ADDR pc; - int *pindex; -{ - 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; - - bl = BLOCKVECTOR (s); - b = BLOCKVECTOR_BLOCK (bl, 0); - - /* Then search that symtab for the smallest block that wins. */ - /* Use binary search to find the last block that starts before PC. */ - - bot = 0; - top = BLOCKVECTOR_NBLOCKS (bl); - - while (top - bot > 1) - { - half = (top - bot + 1) >> 1; - b = BLOCKVECTOR_BLOCK (bl, bot + half); - if (BLOCK_START (b) <= pc) - bot += half; - else - top = bot + half; - } - - /* Now search backward for a block that ends after PC. */ - - while (bot >= 0) - { - b = BLOCKVECTOR_BLOCK (bl, bot); - if (BLOCK_END (b) > pc) - { - if (pindex) - *pindex = bot; - return bl; - } - bot--; - } - - return 0; -} - -/* Return the innermost lexical block containing the specified pc value, - or 0 if there is none. */ - -struct block * -block_for_pc (pc) - register CORE_ADDR pc; -{ - register struct blockvector *bl; - int index; - - bl = blockvector_for_pc (pc, &index); - if (bl) - return BLOCKVECTOR_BLOCK (bl, index); - return 0; -} - -/* Return the function containing pc value PC. - Returns 0 if function is not known. */ - -struct symbol * -find_pc_function (pc) - CORE_ADDR pc; -{ - register struct block *b = block_for_pc (pc); - if (b == 0) - return 0; - return block_function (b); -} - -/* 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; - -/* Clear cache, e.g. when symbol table is discarded. */ - -void -clear_pc_function_cache() -{ - cache_pc_function_low = 0; - cache_pc_function_high = 0; - cache_pc_function_name = (char *)0; -} - -/* 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 - 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. */ - -int -find_pc_partial_function (pc, name, address, endaddr) - CORE_ADDR pc; - char **name; - CORE_ADDR *address; - CORE_ADDR *endaddr; -{ - struct partial_symtab *pst; - struct symbol *f; - struct minimal_symbol *msymbol; - struct partial_symbol *psb; - struct obj_section *sec; - - if (pc >= cache_pc_function_low && pc < cache_pc_function_high) - 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)) - { - cache_pc_function_low = SIGTRAMP_START; - cache_pc_function_high = SIGTRAMP_END; - cache_pc_function_name = ""; - - goto return_cached_value; - } -#endif - - msymbol = lookup_minimal_symbol_by_pc (pc); - pst = find_pc_psymtab (pc); - if (pst) - { - /* Need to read the symbols to get a good value for the end address. */ - if (endaddr != NULL && !pst->readin) - { - /* Need to get the terminal in case symbol-reading produces - output. */ - target_terminal_ours_for_output (); - PSYMTAB_TO_SYMTAB (pst); - } - - if (pst->readin) - { - /* Checking whether the msymbol has a larger value is for the - "pathological" case mentioned in print_frame_info. */ - f = find_pc_function (pc); - 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); - goto return_cached_value; - } - } - else - { - /* 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); - - if (psb - && (msymbol == NULL || - (SYMBOL_VALUE_ADDRESS (psb) - >= SYMBOL_VALUE_ADDRESS (msymbol)))) - { - /* This case isn't being cached currently. */ - if (address) - *address = SYMBOL_VALUE_ADDRESS (psb); - if (name) - *name = SYMBOL_NAME (psb); - /* endaddr non-NULL can't happen here. */ - return 1; - } - } - } - - /* Not in the normal symbol tables, see if the pc is in a known section. - If it's not, then give up. This ensures that anything beyond the end - of the text seg doesn't appear to be part of the last function in the - text segment. */ - - sec = find_pc_section (pc); - - if (!sec) - msymbol = NULL; - - /* Must be in the minimal symbol table. */ - if (msymbol == NULL) - { - /* No available symbol. */ - if (name != NULL) - *name = 0; - if (address != NULL) - *address = 0; - if (endaddr != NULL) - *endaddr = 0; - return 0; - } - - /* See if we're in a transfer table for Sun shared libs. */ - - if (msymbol -> type == mst_text || msymbol -> type == mst_file_text) - cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol); - else - /* It is a transfer table for Sun shared libraries. */ - cache_pc_function_low = pc - FUNCTION_START_OFFSET; - - cache_pc_function_name = SYMBOL_NAME (msymbol); - - /* Use the lesser of the next minimal symbol, or the end of the section, as - the end of the function. */ - - if (SYMBOL_NAME (msymbol + 1) != NULL - && SYMBOL_VALUE_ADDRESS (msymbol + 1) < sec->endaddr) - cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + 1); - 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; - - return_cached_value: - if (address) - *address = cache_pc_function_low; - if (name) - *name = cache_pc_function_name; - if (endaddr) - *endaddr = cache_pc_function_high; - return 1; -} - -/* Return the innermost stack frame executing inside of BLOCK, - or NULL if there is no such frame. If BLOCK is NULL, just return NULL. */ - -FRAME -block_innermost_frame (block) - struct block *block; -{ - struct frame_info *fi; - register FRAME frame; - register CORE_ADDR start; - register CORE_ADDR end; - - if (block == NULL) - return NULL; - - start = BLOCK_START (block); - end = BLOCK_END (block); - - frame = 0; - while (1) - { - frame = get_prev_frame (frame); - if (frame == 0) - return 0; - fi = get_frame_info (frame); - if (fi->pc >= start && fi->pc < end) - return frame; - } -} - -/* Return the full FRAME which corresponds to the given FRAME_ADDR - or NULL if no FRAME on the chain corresponds to FRAME_ADDR. */ - -FRAME -find_frame_addr_in_frame_chain (frame_addr) - FRAME_ADDR frame_addr; -{ - FRAME frame = NULL; - - if (frame_addr == (CORE_ADDR)0) - return NULL; - - while (1) - { - frame = get_prev_frame (frame); - if (frame == NULL) - return NULL; - - if (FRAME_FP (frame) == frame_addr) - return frame; - } -} - -#ifdef SIGCONTEXT_PC_OFFSET -/* Get saved user PC for sigtramp from sigcontext for BSD style sigtramp. */ - -CORE_ADDR -sigtramp_saved_pc (frame) - FRAME frame; -{ - CORE_ADDR sigcontext_addr; - char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT]; - int ptrbytes = TARGET_PTR_BIT / TARGET_CHAR_BIT; - int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT; - - /* Get sigcontext address, it is the third parameter on the stack. */ - if (frame->next) - sigcontext_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next) - + FRAME_ARGS_SKIP + sigcontext_offs, - ptrbytes); - else - sigcontext_addr = read_memory_integer (read_register (SP_REGNUM) - + sigcontext_offs, - ptrbytes); - - /* Don't cause a memory_error when accessing sigcontext in case the stack - layout has changed or the stack is corrupt. */ - target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes); - return extract_unsigned_integer (buf, ptrbytes); -} -#endif /* SIGCONTEXT_PC_OFFSET */ - -void -_initialize_blockframe () -{ - obstack_init (&frame_cache_obstack); -} diff --git a/gnu/usr.bin/gdb/gdb/breakpoint.c b/gnu/usr.bin/gdb/gdb/breakpoint.c deleted file mode 100644 index fe75ed13..0000000 --- a/gnu/usr.bin/gdb/gdb/breakpoint.c +++ /dev/null @@ -1,4052 +0,0 @@ -/* Everything about breakpoints, for GDB. - Copyright 1986, 1987, 1989, 1990, 1991, 1992, 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. */ - -#include "defs.h" -#include -#include "symtab.h" -#include "frame.h" -#include "breakpoint.h" -#include "gdbtypes.h" -#include "expression.h" -#include "gdbcore.h" -#include "gdbcmd.h" -#include "value.h" -#include "ctype.h" -#include "command.h" -#include "inferior.h" -#include "thread.h" -#include "target.h" -#include "language.h" -#include -#include "demangle.h" -#include "annotate.h" - -/* local function prototypes */ - -static void -catch_command_1 PARAMS ((char *, int, int)); - -static void -enable_delete_command PARAMS ((char *, int)); - -static void -enable_delete_breakpoint PARAMS ((struct breakpoint *)); - -static void -enable_once_command PARAMS ((char *, int)); - -static void -enable_once_breakpoint PARAMS ((struct breakpoint *)); - -static void -disable_command PARAMS ((char *, int)); - -static void -disable_breakpoint PARAMS ((struct breakpoint *)); - -static void -enable_command PARAMS ((char *, int)); - -static void -enable_breakpoint PARAMS ((struct breakpoint *)); - -static void -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 void -clear_command PARAMS ((char *, int)); - -static void -catch_command PARAMS ((char *, int)); - -static struct symtabs_and_lines -get_catch_sals PARAMS ((int)); - -static void -watch_command PARAMS ((char *, int)); - -static int -can_use_hardware_watchpoint PARAMS ((struct value *)); - -static void -tbreak_command PARAMS ((char *, int)); - -static void -break_command_1 PARAMS ((char *, int, int)); - -static void -mention PARAMS ((struct breakpoint *)); - -static struct breakpoint * -set_raw_breakpoint PARAMS ((struct symtab_and_line)); - -static void -check_duplicates PARAMS ((CORE_ADDR)); - -static void -describe_other_breakpoints PARAMS ((CORE_ADDR)); - -static void -breakpoints_info PARAMS ((char *, int)); - -static void -breakpoint_1 PARAMS ((int, int)); - -static bpstat -bpstat_alloc PARAMS ((struct breakpoint *, bpstat)); - -static int -breakpoint_cond_eval PARAMS ((char *)); - -static void -cleanup_executing_breakpoints PARAMS ((int)); - -static void -commands_command PARAMS ((char *, int)); - -static void -condition_command PARAMS ((char *, int)); - -static int -get_number PARAMS ((char **)); - -static void -set_breakpoint_count PARAMS ((int)); - -static int -remove_breakpoint PARAMS ((struct breakpoint *)); - -extern int addressprint; /* Print machine addresses? */ - -/* Are we executing breakpoint commands? */ -static int executing_breakpoint_commands; - -/* Walk the following statement or block through all breakpoints. - ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current - breakpoint. */ - -#define ALL_BREAKPOINTS(b) for (b = breakpoint_chain; b; b = b->next) - -#define ALL_BREAKPOINTS_SAFE(b,tmp) \ - for (b = breakpoint_chain; \ - b? (tmp=b->next, 1): 0; \ - b = tmp) - -/* By default no support for hardware watchpoints is assumed. */ -#ifndef TARGET_CAN_USE_HARDWARE_WATCHPOINT -#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) 0 -#define target_remove_watchpoint(ADDR,LEN,TYPE) -1 -#define target_insert_watchpoint(ADDR,LEN,TYPE) -1 -#endif - -#ifndef target_insert_hw_breakpoint -#define target_remove_hw_breakpoint(ADDR,SHADOW) -1 -#define target_insert_hw_breakpoint(ADDR,SHADOW) -1 -#endif - -#ifndef target_stopped_data_address -#define target_stopped_data_address() 0 -#endif - -/* True if breakpoint hit counts should be displayed in breakpoint info. */ - -int show_breakpoint_hit_counts = 1; - -/* Chain of all breakpoints defined. */ - -static struct breakpoint *breakpoint_chain; - -/* Number of last breakpoint made. */ - -static int breakpoint_count; - -/* Set breakpoint count to NUM. */ - -static void -set_breakpoint_count (num) - int num; -{ - breakpoint_count = num; - set_internalvar (lookup_internalvar ("bpnum"), - value_from_longest (builtin_type_int, (LONGEST) num)); -} - -/* Used in run_command to zero the hit count when a new run starts. */ - -void -clear_breakpoint_hit_counts () -{ - struct breakpoint *b; - - ALL_BREAKPOINTS (b) - b->hit_count = 0; -} - -/* Default address, symtab and line to put a breakpoint at - for "break" command with no arg. - if default_breakpoint_valid is zero, the other three are - not valid, and "break" with no arg is an error. - - This set by print_stack_frame, which calls set_default_breakpoint. */ - -int default_breakpoint_valid; -CORE_ADDR default_breakpoint_address; -struct symtab *default_breakpoint_symtab; -int default_breakpoint_line; - -/* *PP is a string denoting a breakpoint. Get the number of the breakpoint. - Advance *PP after the string and any trailing whitespace. - - Currently the string can either be a number or "$" followed by the name - of a convenience variable. Making it an expression wouldn't work well - for map_breakpoint_numbers (e.g. "4 + 5 + 6"). */ -static int -get_number (pp) - char **pp; -{ - int retval; - char *p = *pp; - - if (p == NULL) - /* Empty line means refer to the last breakpoint. */ - return breakpoint_count; - else if (*p == '$') - { - /* Make a copy of the name, so we can null-terminate it - to pass to lookup_internalvar(). */ - char *varname; - char *start = ++p; - value_ptr val; - - while (isalnum (*p) || *p == '_') - p++; - varname = (char *) alloca (p - start + 1); - strncpy (varname, start, p - start); - varname[p - start] = '\0'; - val = value_of_internalvar (lookup_internalvar (varname)); - if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_INT) - error ( -"Convenience variables used to specify breakpoints must have integer values." - ); - retval = (int) value_as_long (val); - } - else - { - if (*p == '-') - ++p; - while (*p >= '0' && *p <= '9') - ++p; - if (p == *pp) - /* There is no number here. (e.g. "cond a == b"). */ - error_no_arg ("breakpoint number"); - retval = atoi (*pp); - } - if (!(isspace (*p) || *p == '\0')) - error ("breakpoint number expected"); - while (isspace (*p)) - p++; - *pp = p; - return retval; -} - -/* condition N EXP -- set break condition of breakpoint N to EXP. */ - -static void -condition_command (arg, from_tty) - char *arg; - int from_tty; -{ - register struct breakpoint *b; - char *p; - register int bnum; - - if (arg == 0) - error_no_arg ("breakpoint number"); - - p = arg; - bnum = get_number (&p); - - ALL_BREAKPOINTS (b) - if (b->number == bnum) - { - if (b->cond) - { - free ((PTR)b->cond); - b->cond = 0; - } - if (b->cond_string != NULL) - free ((PTR)b->cond_string); - - if (*p == 0) - { - b->cond = 0; - b->cond_string = NULL; - if (from_tty) - printf_filtered ("Breakpoint %d now unconditional.\n", bnum); - } - else - { - arg = p; - /* I don't know if it matters whether this is the string the user - typed in or the decompiled expression. */ - b->cond_string = savestring (arg, strlen (arg)); - b->cond = parse_exp_1 (&arg, block_for_pc (b->address), 0); - if (*arg) - error ("Junk at end of expression"); - } - return; - } - - error ("No breakpoint number %d.", bnum); -} - -/* ARGSUSED */ -static void -commands_command (arg, from_tty) - char *arg; - int from_tty; -{ - register struct breakpoint *b; - char *p; - register int bnum; - struct command_line *l; - - /* If we allowed this, we would have problems with when to - free the storage, if we change the commands currently - being read from. */ - - if (executing_breakpoint_commands) - error ("Can't use the \"commands\" command among a breakpoint's commands."); - - p = arg; - bnum = get_number (&p); - if (p && *p) - error ("Unexpected extra arguments following breakpoint number."); - - 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 (); - free_command_lines (&b->commands); - b->commands = l; - breakpoints_changed (); - return; - } - 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. - - Read "memory data" from whatever target or inferior we have. - Returns zero if successful, errno value if not. EIO is used - for address out of bounds. If breakpoints are inserted, returns - shadow contents, not the breakpoints themselves. From breakpoint.c. */ - -int -read_memory_nobpt (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - unsigned len; -{ - int status; - struct breakpoint *b; - - 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. */ - return target_read_memory (memaddr, myaddr, len); - - ALL_BREAKPOINTS (b) - { - if (b->type == bp_watchpoint - || b->type == bp_hardware_watchpoint - || b->type == bp_read_watchpoint - || b->type == bp_access_watchpoint - || !b->inserted) - continue; - else if (b->address + memory_breakpoint_size <= memaddr) - /* The breakpoint is entirely before the chunk of memory - we are reading. */ - continue; - else if (b->address >= memaddr + len) - /* The breakpoint is entirely after 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 (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; - } - } - /* 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. - Both return zero if successful, - or an `errno' value if could not write the inferior. */ - -int -insert_breakpoints () -{ - register struct breakpoint *b; - int val = 0; - int disabled_breaks = 0; - - ALL_BREAKPOINTS (b) - if (b->type != bp_watchpoint - && b->type != bp_hardware_watchpoint - && b->type != bp_read_watchpoint - && b->type != bp_access_watchpoint - && b->enable != 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 defined (DISABLE_UNSETTABLE_BREAK) - if (DISABLE_UNSETTABLE_BREAK (b->address)) - { - val = 0; - b->enable = disabled; - if (!disabled_breaks) - { - target_terminal_ours_for_output (); - fprintf_unfiltered (gdb_stderr, - "Cannot insert breakpoint %d:\n", b->number); - printf_filtered ("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 ((b->type == bp_hardware_watchpoint || - b->type == bp_read_watchpoint || - b->type == bp_access_watchpoint) - && b->enable == enabled - && ! b->inserted - && ! b->duplicate) - { - FRAME 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 - { - FRAME fr = find_frame_addr_in_frame_chain (b->watchpoint_frame); - within_current_scope = (fr != NULL); - if (within_current_scope) - select_frame (fr, -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); - - 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; - - 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); - } - - /* Restore the frame and level. */ - select_frame (saved_frame, saved_level); - } - if (disabled_breaks) - printf_filtered ("\n"); - return val; -} - - -int -remove_breakpoints () -{ - register struct breakpoint *b; - int val; - - ALL_BREAKPOINTS (b) - { - if (b->inserted) - { - val = remove_breakpoint (b); - if (val != 0) - return val; - } - } - return 0; -} - - -static int -remove_breakpoint (b) - struct breakpoint *b; -{ - int val; - - if (b->type != bp_watchpoint - && b->type != bp_hardware_watchpoint - && b->type != bp_read_watchpoint - && b->type != bp_access_watchpoint) - { - 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); - if (val) - return val; - b->inserted = 0; - } - else if ((b->type == bp_hardware_watchpoint || - b->type == bp_read_watchpoint || - b->type == bp_access_watchpoint) - && b->enable == enabled - && ! b->duplicate) - { - value_ptr v, n; - - b->inserted = 0; - /* Walk down the saved value chain. */ - for (v = b->val_chain; v; v = v->next) - { - /* For each memory reference remove the watchpoint - at that address. */ - if (v->lval == lval_memory) - { - int addr, len; - - addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); - len = TYPE_LENGTH (VALUE_TYPE (v)); - val = target_remove_watchpoint (addr, len, b->type); - if (val == -1) - b->inserted = 1; - val = 0; - } - } - /* Failure to remove any of the hardware watchpoints comes here. */ - if (b->inserted) - error ("Hardware watchpoint %d: Could not remove watchpoint\n", - b->number); - - /* Free the saved value chain. We will construct a new one - the next time the watchpoint is inserted. */ - for (v = b->val_chain; v; v = n) - { - n = v->next; - value_free (v); - } - b->val_chain = NULL; - } - return 0; -} - -/* Clear the "inserted" flag in all breakpoints. */ - -void -mark_breakpoints_out () -{ - register struct breakpoint *b; - - ALL_BREAKPOINTS (b) - b->inserted = 0; -} - -/* Clear the "inserted" flag in all breakpoints and delete any breakpoints - which should go away between runs of the program. */ - -void -breakpoint_init_inferior () -{ - register struct breakpoint *b, *temp; - - 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); - - /* Likewise for scope breakpoints. */ - if (b->type == bp_watchpoint_scope) - delete_breakpoint (b); - - /* 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); - } -} - -/* breakpoint_here_p (PC) returns 1 if an enabled breakpoint exists at PC. - When continuing from a location with a breakpoint, - we actually single step once before calling insert_breakpoints. */ - -int -breakpoint_here_p (pc) - CORE_ADDR pc; -{ - register struct breakpoint *b; - - ALL_BREAKPOINTS (b) - if (b->enable != disabled && b->address == pc) - return 1; - - return 0; -} - -/* Return nonzero if FRAME is a dummy frame. We can't use PC_IN_CALL_DUMMY - because figuring out the saved SP would take too much time, at least using - get_saved_register on the 68k. This means that for this function to - work right a port must use the bp_call_dummy breakpoint. */ - -int -frame_in_dummy (frame) - FRAME frame; -{ - struct breakpoint *b; - -#ifdef CALL_DUMMY - ALL_BREAKPOINTS (b) - { - static unsigned LONGEST dummy[] = CALL_DUMMY; - - if (b->type == bp_call_dummy - && b->frame == frame->frame - - /* We need to check the PC as well as the frame on the sparc, - for signals.exp in the testsuite. */ - && (frame->pc - >= (b->address - - sizeof (dummy) / sizeof (LONGEST) * REGISTER_SIZE)) - && frame->pc <= b->address) - return 1; - } -#endif /* CALL_DUMMY */ - return 0; -} - -/* breakpoint_match_thread (PC, PID) returns true if the breakpoint at PC - is valid for process/thread PID. */ - -int -breakpoint_thread_match (pc, pid) - CORE_ADDR pc; - int pid; -{ - struct breakpoint *b; - int thread; - - thread = pid_to_thread_id (pid); - - ALL_BREAKPOINTS (b) - if (b->enable != disabled - && b->address == pc - && (b->thread == -1 || b->thread == thread)) - return 1; - - return 0; -} - - -/* bpstat stuff. External routines' interfaces are documented - in breakpoint.h. */ - -/* Clear a bpstat so that it says we are not at any breakpoint. - Also free any storage that is part of a bpstat. */ - -void -bpstat_clear (bsp) - bpstat *bsp; -{ - bpstat p; - bpstat q; - - if (bsp == 0) - return; - p = *bsp; - while (p != NULL) - { - q = p->next; - if (p->old_val != NULL) - value_free (p->old_val); - free ((PTR)p); - p = q; - } - *bsp = NULL; -} - -/* Return a copy of a bpstat. Like "bs1 = bs2" but all storage that - is part of the bpstat is copied as well. */ - -bpstat -bpstat_copy (bs) - bpstat bs; -{ - bpstat p = NULL; - bpstat tmp; - bpstat retval = NULL; - - if (bs == NULL) - return bs; - - for (; bs != NULL; bs = bs->next) - { - tmp = (bpstat) xmalloc (sizeof (*tmp)); - memcpy (tmp, bs, sizeof (*tmp)); - if (p == NULL) - /* This is the first thing in the chain. */ - retval = tmp; - else - p->next = tmp; - p = tmp; - } - p->next = NULL; - return retval; -} - -/* Find the bpstat associated with this breakpoint */ - -bpstat -bpstat_find_breakpoint(bsp, breakpoint) - bpstat bsp; - struct breakpoint *breakpoint; -{ - if (bsp == NULL) return NULL; - - for (;bsp != NULL; bsp = bsp->next) { - if (bsp->breakpoint_at == breakpoint) return bsp; - } - return NULL; -} - -/* 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 - anything but further calls to bpstat_num). - Return 0 if passed a bpstat which does not indicate any breakpoints. */ - -int -bpstat_num (bsp) - bpstat *bsp; -{ - struct breakpoint *b; - - if ((*bsp) == NULL) - return 0; /* No more breakpoint values */ - else - { - b = (*bsp)->breakpoint_at; - *bsp = (*bsp)->next; - if (b == NULL) - return -1; /* breakpoint that's been deleted since */ - else - return b->number; /* We have its number */ - } -} - -/* Modify BS so that the actions will not be performed. */ - -void -bpstat_clear_actions (bs) - bpstat bs; -{ - for (; bs != NULL; bs = bs->next) - { - bs->commands = NULL; - if (bs->old_val != NULL) - { - value_free (bs->old_val); - bs->old_val = NULL; - } - } -} - -/* Stub for cleaning up our state if we error-out of a breakpoint command */ -/* ARGSUSED */ -static void -cleanup_executing_breakpoints (ignore) - int ignore; -{ - executing_breakpoint_commands = 0; -} - -/* Execute all the commands associated with all the breakpoints at this - location. Any of these commands could cause the process to proceed - beyond this point, etc. We look out for such changes by checking - the global "breakpoint_proceeded" after each command. */ - -void -bpstat_do_actions (bsp) - bpstat *bsp; -{ - bpstat bs; - struct cleanup *old_chain; - - executing_breakpoint_commands = 1; - old_chain = make_cleanup (cleanup_executing_breakpoints, 0); - -top: - bs = *bsp; - - breakpoint_proceeded = 0; - for (; bs != NULL; bs = bs->next) - { - while (bs->commands) - { - char *line = bs->commands->line; - bs->commands = bs->commands->next; - execute_command (line, 0); - /* If the inferior is proceeded by the command, bomb out now. - The bpstat chain has been blown away by wait_for_inferior. - But since execution has stopped again, there is a new bpstat - to look at, so start over. */ - if (breakpoint_proceeded) - goto top; - } - } - - executing_breakpoint_commands = 0; - discard_cleanups (old_chain); -} - -/* 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. */ - -static int -print_it_normal (bs) - bpstat bs; -{ - /* bs->breakpoint_at can be NULL if it was a momentary breakpoint - which has since been deleted. */ - if (bs->breakpoint_at == NULL - || (bs->breakpoint_at->type != bp_breakpoint - && 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; - - 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 - number, not all of them. */ - annotate_breakpoint (bs->breakpoint_at->number); - printf_filtered ("\nBreakpoint %d, ", bs->breakpoint_at->number); - return 0; - } - else if ((bs->old_val != NULL) && - (bs->breakpoint_at->type == bp_watchpoint || - bs->breakpoint_at->type == bp_access_watchpoint || - bs->breakpoint_at->type == bp_hardware_watchpoint)) - { - annotate_watchpoint (bs->breakpoint_at->number); - mention (bs->breakpoint_at); - printf_filtered ("\nOld value = "); - value_print (bs->old_val, gdb_stdout, 0, Val_pretty_default); - printf_filtered ("\nNew value = "); - value_print (bs->breakpoint_at->val, gdb_stdout, 0, - Val_pretty_default); - printf_filtered ("\n"); - value_free (bs->old_val); - bs->old_val = NULL; - /* More than one watchpoint may have been triggered. */ - return -1; - } - else if (bs->breakpoint_at->type == bp_access_watchpoint || - bs->breakpoint_at->type == bp_read_watchpoint) - { - mention (bs->breakpoint_at); - printf_filtered ("\nValue = "); - value_print (bs->breakpoint_at->val, gdb_stdout, 0, - Val_pretty_default); - printf_filtered ("\n"); - return -1; - } - /* We can't deal with it. Maybe another member of the bpstat chain can. */ - 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. */ -int -bpstat_print (bs) - bpstat bs; -{ - int val; - - if (bs == NULL) - return 0; - - val = (*bs->print_it) (bs); - if (val >= 0) - return val; - - /* Maybe another breakpoint in the chain caused us to stop. - (Currently all watchpoints go on the bpstat whether hit or - not. That probably could (should) be changed, provided care is taken - with respect to bpstat_explains_signal). */ - if (bs->next) - return bpstat_print (bs->next); - - /* We reached the end of the chain without printing anything. */ - return 0; -} - -/* Evaluate the expression EXP and return 1 if value is zero. - This is used inside a catch_errors to evaluate the breakpoint condition. - The argument is a "struct expression *" that has been cast to char * to - make it pass through catch_errors. */ - -static int -breakpoint_cond_eval (exp) - char *exp; -{ - value_ptr mark = value_mark (); - int i = !value_true (evaluate_expression ((struct expression *)exp)); - value_free_to_mark (mark); - return i; -} - -/* Allocate a new bpstat and chain it to the current one. */ - -static bpstat -bpstat_alloc (b, cbs) - register struct breakpoint *b; - bpstat cbs; /* Current "bs" value */ -{ - bpstat bs; - - bs = (bpstat) xmalloc (sizeof (*bs)); - cbs->next = bs; - bs->breakpoint_at = b; - /* If the condition is false, etc., don't do the commands. */ - bs->commands = NULL; - bs->old_val = NULL; - bs->print_it = print_it_normal; - return bs; -} - -/* Possible return values for watchpoint_check (this can't be an enum - because of check_errors). */ -/* The watchpoint has been deleted. */ -#define WP_DELETED 1 -/* The value has changed. */ -#define WP_VALUE_CHANGED 2 -/* The value has not changed. */ -#define WP_VALUE_NOT_CHANGED 3 - -/* Check watchpoint condition. */ - -static int -watchpoint_check (p) - char *p; -{ - bpstat bs = (bpstat) p; - struct breakpoint *b; - FRAME saved_frame, fr; - int within_current_scope, saved_level; - - /* 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; - - b = bs->breakpoint_at; - - if (b->exp_valid_block == NULL) - within_current_scope = 1; - else - { - fr = find_frame_addr_in_frame_chain (b->watchpoint_frame); - within_current_scope = (fr != NULL); - if (within_current_scope) - /* If we end up stopping, the current frame will get selected - in normal_stop. So this call to select_frame won't affect - the user. */ - select_frame (fr, -1); - } - - if (within_current_scope) - { - /* We use value_{,free_to_}mark because it could be a - *long* time before we return to the command level and - call free_all_values. We can't call free_all_values because - we might be in the middle of evaluating a function call. */ - - value_ptr mark = value_mark (); - value_ptr new_val = evaluate_expression (bs->breakpoint_at->exp); - if (!value_equal (b->val, new_val)) - { - release_value (new_val); - value_free_to_mark (mark); - bs->old_val = b->val; - b->val = new_val; - /* We will stop here */ - select_frame (saved_frame, saved_level); - return WP_VALUE_CHANGED; - } - else - { - /* Nothing changed, don't do anything. */ - value_free_to_mark (mark); - /* We won't stop here */ - select_frame (saved_frame, saved_level); - return WP_VALUE_NOT_CHANGED; - } - } - else - { - /* This seems like the only logical thing to do because - if we temporarily ignored the watchpoint, then when - we reenter the block in which it is valid it contains - garbage (in the case of a function, it may have two - garbage values, one before and one after the prologue). - So we can't even detect the first assignment to it and - watch after that (since the garbage may or may not equal - the first value assigned). */ - printf_filtered ("\ -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); - - select_frame (saved_frame, saved_level); - return WP_DELETED; - } -} - -/* This is used when everything which needs to be printed has - already been printed. But we still want to print the frame. */ -static int -print_it_done (bs) - bpstat bs; -{ - return 0; -} - -/* This is used when nothing should be printed for this bpstat entry. */ - -static int -print_it_noop (bs) - bpstat bs; -{ - return -1; -} - -/* Get a bpstat associated with having just stopped at address *PC - and frame address FRAME_ADDRESS. Update *PC to point at the - breakpoint (if we hit a breakpoint). NOT_A_BREAKPOINT is nonzero - if this is known to not be a real breakpoint (it could still be a - watchpoint, though). */ - -/* Determine whether we stopped at a breakpoint, etc, or whether we - don't understand this stop. Result is a chain of bpstat's such that: - - if we don't understand the stop, the result is a null pointer. - - if we understand why we stopped, the result is not null. - - Each element of the chain refers to a particular breakpoint or - watchpoint at which we have stopped. (We may have stopped for - several reasons concurrently.) - - Each element of the chain has valid next, breakpoint_at, - commands, FIXME??? fields. - - */ - -bpstat -bpstat_stop_status (pc, frame_address, not_a_breakpoint) - CORE_ADDR *pc; - FRAME_ADDR frame_address; - int not_a_breakpoint; -{ - register struct breakpoint *b; - 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 bpstat root_bs[1]; - /* Pointer to the last thing in the chain currently. */ - bpstat bs = root_bs; - static char message1[] = - "Error evaluating expression for watchpoint %d\n"; - char message[sizeof (message1) + 30 /* slop */]; - - /* Get the address where the breakpoint would have been. */ - bp_addr = *pc - DECR_PC_AFTER_BREAK; - - ALL_BREAKPOINTS (b) - { - if (b->enable == disabled) - continue; - - if (b->type != bp_watchpoint - && b->type != bp_hardware_watchpoint - && b->type != bp_read_watchpoint - && b->type != bp_access_watchpoint - && b->type != bp_hardware_breakpoint - && b->address != bp_addr) - continue; - -#ifndef DECR_PC_AFTER_HW_BREAK -#define DECR_PC_AFTER_HW_BREAK 0 -#endif - if (b->type == bp_hardware_breakpoint - && b->address != (bp_addr - DECR_PC_AFTER_HW_BREAK)) - continue; - - if (b->type != bp_watchpoint - && b->type != bp_hardware_watchpoint - && b->type != bp_read_watchpoint - && b->type != bp_access_watchpoint - && not_a_breakpoint) - continue; - - /* Come here if it's a watchpoint, or if the break address matches */ - - ++(b->hit_count); - - bs = bpstat_alloc (b, bs); /* Alloc a bpstat to explain stop */ - - 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)) - { - case WP_DELETED: - /* We've already printed what needs to be printed. */ - bs->print_it = print_it_done; - /* Stop. */ - break; - case WP_VALUE_CHANGED: - /* Stop. */ - break; - case WP_VALUE_NOT_CHANGED: - /* Don't stop. */ - bs->print_it = print_it_noop; - bs->stop = 0; - continue; - default: - /* Can't happen. */ - /* FALLTHROUGH */ - 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); - /* We've already printed what needs to be printed. */ - bs->print_it = print_it_done; - - /* Stop. */ - break; - } - } - else if (b->type == bp_read_watchpoint || b->type == bp_access_watchpoint) - { - CORE_ADDR addr; - value_ptr v; - int found = 0; - - addr = target_stopped_data_address(); - if (addr == 0) continue; - for (v = b->val_chain; v; v = v->next) - { - if (v->lval == lval_memory) - { - CORE_ADDR vaddr; - - vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); - if (addr == vaddr) - found = 1; - } - } - if (found) - switch (catch_errors (watchpoint_check, (char *) bs, message, - RETURN_MASK_ALL)) - { - case WP_DELETED: - /* We've already printed what needs to be printed. */ - bs->print_it = print_it_done; - /* Stop. */ - break; - case WP_VALUE_CHANGED: - case WP_VALUE_NOT_CHANGED: - /* Stop. */ - 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); - /* 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 - - if (b->frame && b->frame != frame_address) - bs->stop = 0; - else - { - int value_is_zero = 0; - - if (b->cond) - { - /* Need to select the frame, with all that implies - 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), - "Error in testing breakpoint condition:\n", - RETURN_MASK_ALL); - /* FIXME-someday, should give breakpoint # */ - free_all_values (); - } - if (b->cond && value_is_zero) - { - bs->stop = 0; - } - else if (b->ignore_count > 0) - { - b->ignore_count--; - bs->stop = 0; - } - else - { - /* We will stop here */ - if (b->disposition == disable) - b->enable = disabled; - bs->commands = b->commands; - if (b->silent) - bs->print = 0; - if (bs->commands && STREQ ("silent", bs->commands->line)) - { - bs->commands = bs->commands->next; - bs->print = 0; - } - } - } - /* Print nothing for this entry if we dont stop or if we dont print. */ - if (bs->stop == 0 || bs->print == 0) - bs->print_it = print_it_noop; - } - - 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) - { - *pc = bp_addr; -#if defined (SHIFT_INST_REGS) - SHIFT_INST_REGS(); -#else /* No SHIFT_INST_REGS. */ - 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. */ - if (bs && ! bs->stop && - (bs->breakpoint_at->type == bp_hardware_watchpoint || - bs->breakpoint_at->type == bp_read_watchpoint || - bs->breakpoint_at->type == bp_access_watchpoint)) - { - remove_breakpoints (); - insert_breakpoints (); - } - return bs; -} - -/* Tell what to do about this bpstat. */ -struct bpstat_what -bpstat_what (bs) - bpstat bs; -{ - /* Classify each bpstat as one of the following. */ - enum class { - /* This bpstat element has no effect on the main_action. */ - no_effect = 0, - - /* There was a watchpoint, stop but don't print. */ - wp_silent, - - /* There was a watchpoint, stop and print. */ - wp_noisy, - - /* There was a breakpoint but we're not stopping. */ - bp_nostop, - - /* There was a breakpoint, stop but don't print. */ - bp_silent, - - /* There was a breakpoint, stop and print. */ - bp_noisy, - - /* We hit the longjmp breakpoint. */ - long_jump, - - /* We hit the longjmp_resume breakpoint. */ - long_resume, - - /* We hit the step_resume breakpoint. */ - step_resume, - - /* We hit the through_sigtramp breakpoint. */ - through_sig, - - /* This is just used to count how many enums there are. */ - class_last - }; - - /* Here is the table which drives this routine. So that we can - format it pretty, we define some abbreviations for the - enum bpstat_what codes. */ -#define keep_c BPSTAT_WHAT_KEEP_CHECKING -#define stop_s BPSTAT_WHAT_STOP_SILENT -#define stop_n BPSTAT_WHAT_STOP_NOISY -#define single BPSTAT_WHAT_SINGLE -#define setlr BPSTAT_WHAT_SET_LONGJMP_RESUME -#define clrlr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME -#define clrlrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE -#define sr BPSTAT_WHAT_STEP_RESUME -#define ts BPSTAT_WHAT_THROUGH_SIGTRAMP - -/* "Can't happen." Might want to print an error message. - abort() is not out of the question, but chances are GDB is just - a bit confused, not unusable. */ -#define err BPSTAT_WHAT_STOP_NOISY - - /* Given an old action and a class, come up with a new action. */ - /* One interesting property of this table is that wp_silent is the same - as bp_silent and wp_noisy is the same as bp_noisy. That is because - after stopping, the check for whether to step over a breakpoint - (BPSTAT_WHAT_SINGLE type stuff) is handled in proceed() without - reference to how we stopped. We retain separate wp_silent and bp_silent - codes in case we want to change that someday. */ - - /* step_resume entries: a step resume breakpoint overrides another - breakpoint of signal handling (see comment in wait_for_inferior - at first IN_SIGTRAMP where we set the step_resume breakpoint). */ - /* We handle the through_sigtramp_breakpoint the same way; having both - one of those and a step_resume_breakpoint is probably very rare (?). */ - - static const enum bpstat_what_main_action - table[(int)class_last][(int)BPSTAT_WHAT_LAST] = - { - /* old action */ - /* keep_c stop_s stop_n single setlr clrlr clrlrs sr ts - */ -/*no_effect*/ {keep_c,stop_s,stop_n,single, setlr , clrlr , clrlrs, sr, ts}, -/*wp_silent*/ {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts}, -/*wp_noisy*/ {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts}, -/*bp_nostop*/ {single,stop_s,stop_n,single, setlr , clrlrs, clrlrs, sr, ts}, -/*bp_silent*/ {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts}, -/*bp_noisy*/ {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts}, -/*long_jump*/ {setlr ,stop_s,stop_n,setlr , err , err , err , sr, ts}, -/*long_resume*/ {clrlr ,stop_s,stop_n,clrlrs, err , err , err , sr, ts}, -/*step_resume*/ {sr ,sr ,sr ,sr , sr , sr , sr , sr, ts}, -/*through_sig*/ {ts ,ts ,ts ,ts , ts , ts , ts , ts, ts} - }; -#undef keep_c -#undef stop_s -#undef stop_n -#undef single -#undef setlr -#undef clrlr -#undef clrlrs -#undef err -#undef sr -#undef ts - enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING; - struct bpstat_what retval; - - retval.call_dummy = 0; - for (; bs != NULL; bs = bs->next) - { - enum class bs_class = no_effect; - if (bs->breakpoint_at == NULL) - /* I suspect this can happen if it was a momentary breakpoint - which has since been deleted. */ - continue; - switch (bs->breakpoint_at->type) - { - case bp_breakpoint: - case bp_hardware_breakpoint: - case bp_until: - case bp_finish: - if (bs->stop) - { - if (bs->print) - bs_class = bp_noisy; - else - bs_class = bp_silent; - } - else - bs_class = bp_nostop; - break; - case bp_watchpoint: - case bp_hardware_watchpoint: - case bp_read_watchpoint: - case bp_access_watchpoint: - if (bs->stop) - { - if (bs->print) - bs_class = wp_noisy; - else - bs_class = wp_silent; - } - else - /* There was a watchpoint, but we're not stopping. This requires - no further action. */ - bs_class = no_effect; - break; - case bp_longjmp: - bs_class = long_jump; - break; - case bp_longjmp_resume: - bs_class = long_resume; - break; - case bp_step_resume: - if (bs->stop) - { - bs_class = step_resume; - } - else - /* It is for the wrong frame. */ - bs_class = bp_nostop; - break; - case bp_through_sigtramp: - bs_class = through_sig; - break; - case bp_watchpoint_scope: - bs_class = bp_nostop; - break; - - case bp_call_dummy: - /* Make sure the action is stop (silent or noisy), so infrun.c - pops the dummy frame. */ - bs_class = bp_silent; - retval.call_dummy = 1; - break; - } - current_action = table[(int)bs_class][(int)current_action]; - } - retval.main_action = current_action; - return retval; -} - -/* Nonzero if we should step constantly (e.g. watchpoints on machines - without hardware support). This isn't related to a specific bpstat, - just to things like whether watchpoints are set. */ - -int -bpstat_should_step () -{ - struct breakpoint *b; - ALL_BREAKPOINTS (b) - if (b->enable == enabled && b->type == bp_watchpoint) - return 1; - return 0; -} - -/* Print information on breakpoint number BNUM, or -1 if all. - If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS - is nonzero, process only watchpoints. */ - -static void -breakpoint_1 (bnum, allflag) - int bnum; - int allflag; -{ - register struct breakpoint *b; - register struct command_line *l; - 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", - "watchpoint scope", "call dummy" }; - static char *bpdisps[] = {"del", "dis", "keep"}; - static char bpenables[] = "ny"; - char wrap_indent[80]; - - ALL_BREAKPOINTS (b) - if (bnum == -1 - || bnum == b->number) - { -/* We only print out user settable breakpoints unless the allflag is set. */ - if (!allflag - && b->type != bp_breakpoint - && b->type != bp_hardware_breakpoint - && b->type != bp_watchpoint - && b->type != bp_read_watchpoint - && b->type != bp_access_watchpoint - && b->type != bp_hardware_watchpoint) - continue; - - if (!found_a_breakpoint++) - { - annotate_breakpoints_headers (); - - annotate_field (0); - printf_filtered ("Num "); - annotate_field (1); - printf_filtered ("Type "); - annotate_field (2); - printf_filtered ("Disp "); - annotate_field (3); - printf_filtered ("Enb "); - if (addressprint) - { - annotate_field (4); - printf_filtered ("Address "); - } - annotate_field (5); - printf_filtered ("What\n"); - - annotate_breakpoints_table (); - } - - annotate_record (); - annotate_field (0); - printf_filtered ("%-3d ", b->number); - annotate_field (1); - printf_filtered ("%-14s ", bptypes[(int)b->type]); - annotate_field (2); - printf_filtered ("%-4s ", bpdisps[(int)b->disposition]); - annotate_field (3); - printf_filtered ("%-3c ", bpenables[(int)b->enable]); - - strcpy (wrap_indent, " "); - if (addressprint) - strcat (wrap_indent, " "); - switch (b->type) - { - case bp_watchpoint: - case bp_hardware_watchpoint: - case bp_read_watchpoint: - case bp_access_watchpoint: - /* 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); - print_expression (b->exp, gdb_stdout); - break; - - case bp_breakpoint: - case bp_hardware_breakpoint: - case bp_until: - case bp_finish: - case bp_longjmp: - case bp_longjmp_resume: - case bp_step_resume: - case bp_through_sigtramp: - case bp_watchpoint_scope: - case bp_call_dummy: - if (addressprint) - { - annotate_field (4); - /* FIXME-32x64: need a print_address_numeric with - field width */ - printf_filtered - ("%s ", - local_hex_string_custom - ((unsigned long) b->address, "08l")); - } - - annotate_field (5); - - last_addr = b->address; - if (b->source_file) - { - sym = find_pc_function (b->address); - 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 (b->source_file, gdb_stdout); - printf_filtered (":%d", b->line_number); - } - else - print_address_symbolic (b->address, gdb_stdout, demangle, " "); - break; - } - - printf_filtered ("\n"); - - if (b->frame) - { - annotate_field (6); - - printf_filtered ("\tstop only in stack frame at "); - print_address_numeric (b->frame, 1, gdb_stdout); - printf_filtered ("\n"); - } - - if (b->cond) - { - annotate_field (7); - - printf_filtered ("\tstop only if "); - print_expression (b->cond, gdb_stdout); - printf_filtered ("\n"); - } - - if (show_breakpoint_hit_counts && b->hit_count) - { - /* FIXME should make an annotation for this */ - - printf_filtered ("\tbreakpoint already hit %d times\n", - b->hit_count); - } - - if (b->ignore_count) - { - annotate_field (8); - - printf_filtered ("\tignore next %d hits\n", b->ignore_count); - } - - if ((l = b->commands)) - { - annotate_field (9); - - while (l) - { - fputs_filtered ("\t", gdb_stdout); - fputs_filtered (l->line, gdb_stdout); - fputs_filtered ("\n", gdb_stdout); - l = l->next; - } - } - } - - if (!found_a_breakpoint) - { - if (bnum == -1) - printf_filtered ("No breakpoints or watchpoints.\n"); - else - printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum); - } - else - /* Compare against (CORE_ADDR)-1 in case some compiler decides - that a comparison of an unsigned with -1 is always false. */ - if (last_addr != (CORE_ADDR)-1) - set_next_address (last_addr); - - annotate_breakpoints_table_end (); -} - -/* ARGSUSED */ -static void -breakpoints_info (bnum_exp, from_tty) - char *bnum_exp; - int from_tty; -{ - int bnum = -1; - - if (bnum_exp) - bnum = parse_and_eval_address (bnum_exp); - - breakpoint_1 (bnum, 0); -} - -#if MAINTENANCE_CMDS - -/* ARGSUSED */ -static void -maintenance_info_breakpoints (bnum_exp, from_tty) - char *bnum_exp; - int from_tty; -{ - int bnum = -1; - - if (bnum_exp) - bnum = parse_and_eval_address (bnum_exp); - - breakpoint_1 (bnum, 1); -} - -#endif - -/* Print a message describing any breakpoints set at PC. */ - -static void -describe_other_breakpoints (pc) - register CORE_ADDR pc; -{ - register int others = 0; - register struct breakpoint *b; - - ALL_BREAKPOINTS (b) - if (b->address == pc) - 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) ? " (disabled)" : "", - (others > 1) ? "," : ((others == 1) ? " and" : "")); - } - printf_filtered ("also set at pc "); - print_address_numeric (pc, 1, gdb_stdout); - printf_filtered (".\n"); - } -} - -/* Set the default place to put a breakpoint - for the `break' command with no arguments. */ - -void -set_default_breakpoint (valid, addr, symtab, line) - int valid; - CORE_ADDR addr; - struct symtab *symtab; - int line; -{ - default_breakpoint_valid = valid; - default_breakpoint_address = addr; - default_breakpoint_symtab = symtab; - default_breakpoint_line = line; -} - -/* Rescan breakpoints at address ADDRESS, - marking the first one as "first" and any others as "duplicates". - This is so that the bpt instruction is only inserted once. */ - -static void -check_duplicates (address) - CORE_ADDR address; -{ - register struct breakpoint *b; - register int count = 0; - - if (address == 0) /* Watchpoints are uninteresting */ - return; - - ALL_BREAKPOINTS (b) - if (b->enable != disabled && b->address == address) - { - count++; - b->duplicate = count > 1; - } -} - -/* Low level routine to set a breakpoint. - Takes as args the three things that every breakpoint must have. - Returns the breakpoint object so caller can set other things. - Does not set the breakpoint number! - Does not print anything. - - ==> This routine should not be called if there is a chance of later - error(); otherwise it leaves a bogus breakpoint on the chain. Validate - your arguments BEFORE calling this routine! */ - -static struct breakpoint * -set_raw_breakpoint (sal) - struct symtab_and_line sal; -{ - register struct breakpoint *b, *b1; - - b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint)); - memset (b, 0, sizeof (*b)); - b->address = sal.pc; - if (sal.symtab == NULL) - b->source_file = NULL; - else - b->source_file = savestring (sal.symtab->filename, - strlen (sal.symtab->filename)); - b->thread = -1; - b->line_number = sal.line; - b->enable = enabled; - b->next = 0; - b->silent = 0; - b->ignore_count = 0; - b->commands = NULL; - b->frame = 0; - - /* Add this breakpoint to the end of the chain - so that a list of breakpoints will come out in order - of increasing numbers. */ - - b1 = breakpoint_chain; - if (b1 == 0) - breakpoint_chain = b; - else - { - while (b1->next) - b1 = b1->next; - b1->next = b; - } - - check_duplicates (sal.pc); - breakpoints_changed (); - - return b; -} - -static void -create_longjmp_breakpoint(func_name) - char *func_name; -{ - struct symtab_and_line sal; - struct breakpoint *b; - static int internal_breakpoint_number = -1; - - if (func_name != NULL) - { - struct minimal_symbol *m; - - m = lookup_minimal_symbol(func_name, (struct objfile *)NULL); - if (m) - sal.pc = SYMBOL_VALUE_ADDRESS (m); - else - return; - } - else - sal.pc = 0; - - sal.symtab = NULL; - sal.line = 0; - - b = set_raw_breakpoint(sal); - if (!b) return; - - b->type = func_name != NULL ? bp_longjmp : bp_longjmp_resume; - b->disposition = donttouch; - b->enable = disabled; - b->silent = 1; - if (func_name) - b->addr_string = strsave(func_name); - b->number = internal_breakpoint_number--; -} - -/* Call this routine when stepping and nexting to enable a breakpoint if we do - a longjmp(). When we hit that breakpoint, call - set_longjmp_resume_breakpoint() to figure out where we are going. */ - -void -enable_longjmp_breakpoint() -{ - register struct breakpoint *b; - - ALL_BREAKPOINTS (b) - if (b->type == bp_longjmp) - { - b->enable = enabled; - check_duplicates (b->address); - } -} - -void -disable_longjmp_breakpoint() -{ - register struct breakpoint *b; - - ALL_BREAKPOINTS (b) - if ( b->type == bp_longjmp - || b->type == bp_longjmp_resume) - { - b->enable = disabled; - check_duplicates (b->address); - } -} - -int -hw_breakpoint_used_count() -{ - register struct breakpoint *b; - int i = 0; - - ALL_BREAKPOINTS (b) - { - if (b->type == bp_hardware_breakpoint && b->enable == enabled) - i++; - } - - return i; -} - -int -hw_watchpoint_used_count(type, other_type_used) - enum bptype type; - int *other_type_used; -{ - register struct breakpoint *b; - int i = 0; - - *other_type_used = 0; - ALL_BREAKPOINTS (b) - { - if (b->enable == enabled) - { - if (b->type == type) i++; - else if ((b->type == bp_hardware_watchpoint || - b->type == bp_read_watchpoint || - b->type == bp_access_watchpoint) - && b->enable == enabled) - *other_type_used = 1; - } - } - return i; -} - -/* Call this after hitting the longjmp() breakpoint. Use this to set a new - breakpoint at the target of the jmp_buf. - - FIXME - This ought to be done by setting a temporary breakpoint that gets - deleted automatically... -*/ - -void -set_longjmp_resume_breakpoint(pc, frame) - CORE_ADDR pc; - FRAME frame; -{ - register struct breakpoint *b; - - ALL_BREAKPOINTS (b) - if (b->type == bp_longjmp_resume) - { - b->address = pc; - b->enable = enabled; - if (frame != NULL) - b->frame = FRAME_FP(frame); - else - b->frame = 0; - check_duplicates (b->address); - return; - } -} - -/* Set a breakpoint that will evaporate an end of command - at address specified by SAL. - Restrict it to frame FRAME if FRAME is nonzero. */ - -struct breakpoint * -set_momentary_breakpoint (sal, frame, type) - struct symtab_and_line sal; - FRAME frame; - enum bptype type; -{ - register struct breakpoint *b; - b = set_raw_breakpoint (sal); - b->type = type; - b->enable = enabled; - b->disposition = donttouch; - b->frame = (frame ? FRAME_FP (frame) : 0); - return b; -} - -#if 0 -void -clear_momentary_breakpoints () -{ - register struct breakpoint *b; - ALL_BREAKPOINTS (b) - if (b->disposition == delete) - { - delete_breakpoint (b); - break; - } -} -#endif - -/* Tell the user we have just set a breakpoint B. */ - -static void -mention (b) - struct breakpoint *b; -{ - int say_where = 0; - - switch (b->type) - { - case bp_watchpoint: - printf_filtered ("Watchpoint %d: ", b->number); - print_expression (b->exp, gdb_stdout); - break; - case bp_hardware_watchpoint: - printf_filtered ("Hardware watchpoint %d: ", b->number); - print_expression (b->exp, gdb_stdout); - break; - case bp_read_watchpoint: - printf_filtered ("Hardware read watchpoint %d: ", b->number); - print_expression (b->exp, gdb_stdout); - break; - case bp_access_watchpoint: - printf_filtered ("Hardware access(read/write) watchpoint %d: ",b->number); - print_expression (b->exp, gdb_stdout); - break; - case bp_breakpoint: - printf_filtered ("Breakpoint %d", b->number); - say_where = 1; - break; - case bp_hardware_breakpoint: - printf_filtered ("Hardware assisted breakpoint %d", b->number); - say_where = 1; - break; - case bp_until: - case bp_finish: - case bp_longjmp: - case bp_longjmp_resume: - case bp_step_resume: - case bp_through_sigtramp: - case bp_call_dummy: - case bp_watchpoint_scope: - break; - } - if (say_where) - { - if (addressprint || b->source_file == NULL) - { - printf_filtered (" at "); - print_address_numeric (b->address, 1, gdb_stdout); - } - if (b->source_file) - printf_filtered (": file %s, line %d.", - b->source_file, b->line_number); - } - 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. - second bit : 0 normal breakpoint, 1 hardware breakpoint. */ - -static void -break_command_1 (arg, flag, from_tty) - char *arg; - int flag, from_tty; -{ - int tempflag, hardwareflag; - struct symtabs_and_lines sals; - struct symtab_and_line sal; - register struct expression *cond = 0; - register struct breakpoint *b; - - /* Pointers in arg to the start, and one past the end, of the condition. */ - char *cond_start = NULL; - char *cond_end = NULL; - /* Pointers in arg to the start, and one past the end, - of the address part. */ - char *addr_start = NULL; - char *addr_end = NULL; - struct cleanup *old_chain; - struct cleanup *canonical_strings_chain = NULL; - char **canonical = (char **)NULL; - int i; - int thread; - - hardwareflag = flag & 2; - tempflag = flag & 1; - - sals.sals = NULL; - sals.nelts = 0; - - sal.line = sal.pc = sal.end = 0; - sal.symtab = 0; - - /* If no arg given, or if first arg is 'if ', use the default breakpoint. */ - - if (!arg || (arg[0] == 'i' && arg[1] == 'f' - && (arg[2] == ' ' || arg[2] == '\t'))) - { - if (default_breakpoint_valid) - { - sals.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - sal.pc = default_breakpoint_address; - sal.line = default_breakpoint_line; - sal.symtab = default_breakpoint_symtab; - sals.sals[0] = sal; - sals.nelts = 1; - } - else - error ("No default breakpoint address now."); - } - else - { - addr_start = arg; - - /* Force almost all breakpoints to be in terms of the - current_source_symtab (which is decode_line_1's default). This - should produce the results we want almost all of the time while - leaving default_breakpoint_* alone. */ - if (default_breakpoint_valid - && (!current_source_symtab - || (arg && (*arg == '+' || *arg == '-')))) - sals = decode_line_1 (&arg, 1, default_breakpoint_symtab, - default_breakpoint_line, &canonical); - else - sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0, &canonical); - - addr_end = arg; - } - - if (! sals.nelts) - return; - - /* Make sure that all storage allocated in decode_line_1 gets freed in case - the following `for' loop 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); - for (i = 0; i < sals.nelts; i++) - { - if (canonical[i] != NULL) - make_cleanup (free, canonical[i]); - } - } - - thread = -1; /* No specific thread yet */ - - /* Resolve all line numbers to PC's, and verify that conditions - can be parsed, before setting any breakpoints. */ - for (i = 0; i < sals.nelts; i++) - { - char *tok, *end_tok; - int toklen; - - resolve_sal_pc (&sals.sals[i]); - - tok = arg; - - while (tok && *tok) - { - while (*tok == ' ' || *tok == '\t') - tok++; - - end_tok = tok; - - while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000') - end_tok++; - - toklen = end_tok - tok; - - if (toklen >= 1 && strncmp (tok, "if", toklen) == 0) - { - tok = cond_start = end_tok + 1; - cond = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0); - cond_end = tok; - } - else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0) - { - char *tmptok; - - tok = end_tok + 1; - tmptok = tok; - thread = strtol (tok, &tok, 0); - if (tok == tmptok) - error ("Junk after thread keyword."); - if (!valid_thread_id (thread)) - error ("Unknown thread %d\n", thread); - } - else - error ("Junk at end of arguments."); - } - } - if (hardwareflag) - { - int i, target_resources_ok; - - i = hw_breakpoint_used_count (); - target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT ( - bp_hardware_breakpoint, i + sals.nelts, 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."); - } - - /* Remove the canonical strings from the cleanup, they are needed below. */ - if (canonical != (char **)NULL) - discard_cleanups (canonical_strings_chain); - - /* Now set all the breakpoints. */ - for (i = 0; i < sals.nelts; i++) - { - sal = sals.sals[i]; - - if (from_tty) - describe_other_breakpoints (sal.pc); - - b = set_raw_breakpoint (sal); - set_breakpoint_count (breakpoint_count + 1); - b->number = breakpoint_count; - b->type = hardwareflag ? bp_hardware_breakpoint : bp_breakpoint; - b->cond = cond; - b->thread = thread; - - /* If a canonical line spec is needed use that instead of the - command string. */ - if (canonical != (char **)NULL && canonical[i] != NULL) - b->addr_string = canonical[i]; - else if (addr_start) - b->addr_string = savestring (addr_start, addr_end - addr_start); - if (cond_start) - b->cond_string = savestring (cond_start, cond_end - cond_start); - - b->enable = enabled; - b->disposition = tempflag ? delete : donttouch; - - mention (b); - } - - 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 -resolve_sal_pc (sal) - struct symtab_and_line *sal; -{ - CORE_ADDR pc; - - if (sal->pc == 0 && sal->symtab != 0) - { - pc = find_line_pc (sal->symtab, sal->line); - if (pc == 0) - error ("No line %d in file \"%s\".", - sal->line, sal->symtab->filename); - sal->pc = pc; - } -} - -#define BP_TEMPFLAG 1 -#define BP_HARDWAREFLAG 2 -void -break_command (arg, from_tty) - char *arg; - int from_tty; -{ - break_command_1 (arg, 0, from_tty); -} - -static void -tbreak_command (arg, from_tty) - char *arg; - int from_tty; -{ - break_command_1 (arg, BP_TEMPFLAG, from_tty); -} - -static void -hbreak_command (arg, from_tty) - char *arg; - int from_tty; -{ - break_command_1 (arg, BP_HARDWAREFLAG, from_tty); -} - -static void -thbreak_command (arg, from_tty) - char *arg; - int from_tty; -{ - break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty); -} - -/* ARGSUSED */ -/* accessflag: 0: watch write, 1: watch read, 2: watch access(read or write) -*/ -static void -watch_command_1 (arg, accessflag, from_tty) - char *arg; - int accessflag; - int from_tty; -{ - struct breakpoint *b; - struct symtab_and_line sal; - struct expression *exp; - struct block *exp_valid_block; - struct value *val, *mark; - FRAME frame, prev_frame; - char *exp_start = NULL; - char *exp_end = NULL; - char *tok, *end_tok; - int toklen; - char *cond_start = NULL; - char *cond_end = NULL; - struct expression *cond = NULL; - int i, other_type_used, target_resources_ok; - enum bptype bp_type; - int mem_cnt = 0; - - sal.pc = 0; - sal.symtab = NULL; - sal.line = 0; - - /* Parse arguments. */ - innermost_block = NULL; - exp_start = arg; - exp = parse_exp_1 (&arg, 0, 0); - exp_end = arg; - exp_valid_block = innermost_block; - mark = value_mark (); - val = evaluate_expression (exp); - release_value (val); - if (VALUE_LAZY (val)) - value_fetch_lazy (val); - - tok = arg; - while (*tok == ' ' || *tok == '\t') - tok++; - end_tok = tok; - - while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000') - end_tok++; - - toklen = end_tok - tok; - if (toklen >= 1 && strncmp (tok, "if", toklen) == 0) - { - tok = cond_start = end_tok + 1; - cond = parse_exp_1 (&tok, 0, 0); - cond_end = tok; - } - if (*tok) - error("Junk at end of command."); - - if (accessflag == 1) bp_type = bp_read_watchpoint; - else if (accessflag == 2) bp_type = bp_access_watchpoint; - else bp_type = bp_hardware_watchpoint; - - mem_cnt = can_use_hardware_watchpoint (val); - if (mem_cnt == 0 && bp_type != bp_hardware_watchpoint) - error ("Expression cannot be implemented with read/access watchpoint."); - if (mem_cnt != 0) { - i = hw_watchpoint_used_count (bp_type, &other_type_used); - target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT( - bp_type, i + mem_cnt, other_type_used); - if (target_resources_ok == 0 && bp_type != bp_hardware_watchpoint) - error ("Target does not have this type of hardware watchpoint support."); - if (target_resources_ok < 0 && bp_type != bp_hardware_watchpoint) - error ("Target resources have been allocated for other types of watchpoints."); - } - - /* Now set up the breakpoint. */ - b = set_raw_breakpoint (sal); - set_breakpoint_count (breakpoint_count + 1); - b->number = breakpoint_count; - b->disposition = donttouch; - b->exp = exp; - b->exp_valid_block = exp_valid_block; - b->exp_string = savestring (exp_start, exp_end - exp_start); - b->val = val; - b->cond = cond; - if (cond_start) - b->cond_string = savestring (cond_start, cond_end - cond_start); - else - b->cond_string = 0; - - frame = block_innermost_frame (exp_valid_block); - if (frame) - { - prev_frame = get_prev_frame (frame); - b->watchpoint_frame = FRAME_FP (frame); - } - else - b->watchpoint_frame = (CORE_ADDR)0; - - if (mem_cnt && target_resources_ok > 0) - b->type = bp_type; - else - b->type = bp_watchpoint; - - /* If the expression is "local", then set up a "watchpoint scope" - breakpoint at the point where we've left the scope of the watchpoint - 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; - - scope_breakpoint = set_raw_breakpoint (scope_sal); - set_breakpoint_count (breakpoint_count + 1); - scope_breakpoint->number = breakpoint_count; - - scope_breakpoint->type = bp_watchpoint_scope; - scope_breakpoint->enable = enabled; - - /* Automatically delete the breakpoint when it hits. */ - scope_breakpoint->disposition = delete; - - /* Only break in the proper frame (help with recursion). */ - scope_breakpoint->frame = prev_frame->frame; - - /* Set the address at which we will stop. */ - scope_breakpoint->address = get_frame_pc (prev_frame); - - /* The scope breakpoint is related to the watchpoint. We - will need to act on them together. */ - b->related_breakpoint = scope_breakpoint; - } - } - value_free_to_mark (mark); - mention (b); -} - -/* Return count of locations need to be watched and can be handled - in hardware. If the watchpoint can not be handled - in hardware return zero. */ - -static int -can_use_hardware_watchpoint (v) - struct value *v; -{ - int found_memory_cnt = 0; - - /* Make sure all the intermediate values are in memory. Also make sure - we found at least one memory expression. Guards against watch 0x12345, - which is meaningless, but could cause errors if one tries to insert a - hardware watchpoint for the constant expression. */ - for ( ; v; v = v->next) - { - if (v->lval == lval_memory) - { - if (TYPE_LENGTH (VALUE_TYPE (v)) <= REGISTER_SIZE) - found_memory_cnt++; - } - else if (v->lval != not_lval && v->modifiable == 0) - return 0; - } - - /* The expression itself looks suitable for using a hardware - watchpoint, but give the target machine a chance to reject it. */ - return found_memory_cnt; -} - -static void watch_command (arg, from_tty) - char *arg; - int from_tty; -{ - watch_command_1 (arg, 0, from_tty); -} - -static void rwatch_command (arg, from_tty) - char *arg; - int from_tty; -{ - watch_command_1 (arg, 1, from_tty); -} - -static void awatch_command (arg, from_tty) - char *arg; - int from_tty; -{ - watch_command_1 (arg, 2, from_tty); -} - - -/* - * Helper routine for the until_command routine in infcmd.c. Here - * because it uses the mechanisms of breakpoints. - */ -/* ARGSUSED */ -void -until_break_command (arg, from_tty) - char *arg; - int from_tty; -{ - struct symtabs_and_lines sals; - struct symtab_and_line sal; - FRAME prev_frame = get_prev_frame (selected_frame); - struct breakpoint *breakpoint; - struct cleanup *old_chain; - - clear_proceed_status (); - - /* Set a breakpoint where the user wants it and at return from - this function */ - - if (default_breakpoint_valid) - sals = decode_line_1 (&arg, 1, default_breakpoint_symtab, - default_breakpoint_line, (char ***)NULL); - else - sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0, (char ***)NULL); - - if (sals.nelts != 1) - error ("Couldn't get information on specified line."); - - sal = sals.sals[0]; - free ((PTR)sals.sals); /* malloc'd, so freed */ - - if (*arg) - error ("Junk at end of arguments."); - - resolve_sal_pc (&sal); - - breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until); - - old_chain = make_cleanup(delete_breakpoint, breakpoint); - - /* Keep within the current frame */ - - if (prev_frame) - { - struct frame_info *fi; - - fi = get_frame_info (prev_frame); - sal = find_pc_line (fi->pc, 0); - sal.pc = fi->pc; - breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until); - make_cleanup(delete_breakpoint, breakpoint); - } - - proceed (-1, TARGET_SIGNAL_DEFAULT, 0); - do_cleanups(old_chain); -} - -#if 0 -/* These aren't used; I don't konw what they were for. */ -/* Set a breakpoint at the catch clause for NAME. */ -static int -catch_breakpoint (name) - char *name; -{ -} - -static int -disable_catch_breakpoint () -{ -} - -static int -delete_catch_breakpoint () -{ -} - -static int -enable_catch_breakpoint () -{ -} -#endif /* 0 */ - -struct sal_chain -{ - struct sal_chain *next; - struct symtab_and_line sal; -}; - -#if 0 -/* 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. */ -static struct symtabs_and_lines -map_catch_names (args, function) - char *args; - int (*function)(); -{ - register char *p = args; - register char *p1; - struct symtabs_and_lines sals; -#if 0 - struct sal_chain *sal_chain = 0; -#endif - - if (p == 0) - error_no_arg ("one or more catch names"); - - sals.nelts = 0; - sals.sals = NULL; - - while (*p) - { - p1 = p; - /* Don't swallow conditional part. */ - if (p1[0] == 'i' && p1[1] == 'f' - && (p1[2] == ' ' || p1[2] == '\t')) - break; - - if (isalpha (*p1)) - { - p1++; - while (isalnum (*p1) || *p1 == '_' || *p1 == '$') - p1++; - } - - if (*p1 && *p1 != ' ' && *p1 != '\t') - error ("Arguments must be catch names."); - - *p1 = 0; -#if 0 - if (function (p)) - { - 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; - goto win; - } -#endif - printf_unfiltered ("No catch clause for exception %s.\n", p); -#if 0 - win: -#endif - p = p1; - while (*p == ' ' || *p == '\t') p++; - } -} -#endif /* 0 */ - -/* This shares a lot of code with `print_frame_label_vars' from stack.c. */ - -static struct symtabs_and_lines -get_catch_sals (this_level_only) - int this_level_only; -{ - register struct blockvector *bl; - register struct block *block; - int index, have_default = 0; - struct frame_info *fi; - CORE_ADDR pc; - struct symtabs_and_lines sals; - struct sal_chain *sal_chain = 0; - char *blocks_searched; - - /* Not sure whether an error message is always the correct response, - but it's better than a core dump. */ - if (selected_frame == NULL) - error ("No selected frame."); - block = get_frame_block (selected_frame); - fi = get_frame_info (selected_frame); - pc = fi->pc; - - sals.nelts = 0; - sals.sals = NULL; - - if (block == 0) - error ("No symbol table info available.\n"); - - bl = blockvector_for_pc (BLOCK_END (block) - 4, &index); - blocks_searched = (char *) alloca (BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); - memset (blocks_searched, 0, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); - - while (block != 0) - { - CORE_ADDR end = BLOCK_END (block) - 4; - int last_index; - - if (bl != blockvector_for_pc (end, &index)) - error ("blockvector blotch"); - if (BLOCKVECTOR_BLOCK (bl, index) != block) - error ("blockvector botch"); - last_index = BLOCKVECTOR_NBLOCKS (bl); - index += 1; - - /* Don't print out blocks that have gone by. */ - while (index < last_index - && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < pc) - index++; - - while (index < last_index - && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < end) - { - if (blocks_searched[index] == 0) - { - struct block *b = BLOCKVECTOR_BLOCK (bl, index); - int nsyms; - register int i; - register struct symbol *sym; - - nsyms = BLOCK_NSYMS (b); - - for (i = 0; i < nsyms; i++) - { - sym = BLOCK_SYM (b, i); - if (STREQ (SYMBOL_NAME (sym), "default")) - { - if (have_default) - continue; - have_default = 1; - } - if (SYMBOL_CLASS (sym) == LOC_LABEL) - { - struct sal_chain *next = (struct sal_chain *) - alloca (sizeof (struct sal_chain)); - next->next = sal_chain; - next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0); - sal_chain = next; - } - } - blocks_searched[index] = 1; - } - index++; - } - if (have_default) - break; - if (sal_chain && this_level_only) - break; - - /* After handling the function's top-level block, stop. - Don't continue to its superblock, the block of - per-file symbols. */ - if (BLOCK_FUNCTION (block)) - break; - block = BLOCK_SUPERBLOCK (block); - } - - if (sal_chain) - { - struct sal_chain *tmp_chain; - - /* Count the number of entries. */ - for (index = 0, tmp_chain = sal_chain; tmp_chain; - tmp_chain = tmp_chain->next) - index++; - - sals.nelts = index; - sals.sals = (struct symtab_and_line *) - xmalloc (index * sizeof (struct symtab_and_line)); - for (index = 0; sal_chain; sal_chain = sal_chain->next, index++) - sals.sals[index] = sal_chain->sal; - } - - return sals; -} - -/* Commands to deal with catching exceptions. */ - -static void -catch_command_1 (arg, tempflag, from_tty) - char *arg; - int tempflag; - int from_tty; -{ - /* First, translate ARG into something we can deal with in terms - of breakpoints. */ - - struct symtabs_and_lines sals; - struct symtab_and_line sal; - register struct expression *cond = 0; - register struct breakpoint *b; - char *save_arg; - int i; - - sal.line = sal.pc = sal.end = 0; - sal.symtab = 0; - - /* If no arg given, or if first arg is 'if ', all active catch clauses - are breakpointed. */ - - if (!arg || (arg[0] == 'i' && arg[1] == 'f' - && (arg[2] == ' ' || arg[2] == '\t'))) - { - /* Grab all active catch clauses. */ - sals = get_catch_sals (0); - } - else - { - /* Grab selected catch clauses. */ - error ("catch NAME not implemented"); -#if 0 - /* This isn't used; I don't know what it was for. */ - sals = map_catch_names (arg, catch_breakpoint); -#endif - } - - if (! sals.nelts) - return; - - save_arg = arg; - for (i = 0; i < sals.nelts; i++) - { - resolve_sal_pc (&sals.sals[i]); - - while (arg && *arg) - { - if (arg[0] == 'i' && arg[1] == 'f' - && (arg[2] == ' ' || arg[2] == '\t')) - cond = parse_exp_1 ((arg += 2, &arg), - block_for_pc (sals.sals[i].pc), 0); - else - error ("Junk at end of arguments."); - } - arg = save_arg; - } - - for (i = 0; i < sals.nelts; i++) - { - sal = sals.sals[i]; - - if (from_tty) - 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 = cond; - b->enable = enabled; - b->disposition = tempflag ? delete : donttouch; - - mention (b); - } - - if (sals.nelts > 1) - { - printf_unfiltered ("Multiple breakpoints were set.\n"); - printf_unfiltered ("Use the \"delete\" command to delete unwanted breakpoints.\n"); - } - free ((PTR)sals.sals); -} - -#if 0 -/* These aren't used; I don't know what they were for. */ -/* Disable breakpoints on all catch clauses described in ARGS. */ -static void -disable_catch (args) - char *args; -{ - /* Map the disable command to catch clauses described in ARGS. */ -} - -/* Enable breakpoints on all catch clauses described in ARGS. */ -static void -enable_catch (args) - char *args; -{ - /* Map the disable command to catch clauses described in ARGS. */ -} - -/* Delete breakpoints on all catch clauses in the active scope. */ -static void -delete_catch (args) - char *args; -{ - /* Map the delete command to catch clauses described in ARGS. */ -} -#endif /* 0 */ - -static void -catch_command (arg, from_tty) - char *arg; - int from_tty; -{ - catch_command_1 (arg, 0, from_tty); -} - -static void -clear_command (arg, from_tty) - char *arg; - int from_tty; -{ - register struct breakpoint *b, *b1; - struct symtabs_and_lines sals; - struct symtab_and_line sal; - register struct breakpoint *found; - int i; - - if (arg) - { - sals = decode_line_spec (arg, 1); - } - else - { - sals.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); - sal.line = default_breakpoint_line; - sal.symtab = default_breakpoint_symtab; - sal.pc = 0; - if (sal.symtab == 0) - error ("No source file specified."); - - sals.sals[0] = sal; - sals.nelts = 1; - } - - 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. */ - 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))) - { - b1 = breakpoint_chain; - breakpoint_chain = b1->next; - b1->next = found; - found = b1; - } - - 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))) - { - b1 = b->next; - b->next = b1->next; - b1->next = found; - found = b1; - } - - if (found == 0) - { - if (arg) - error ("No breakpoint at %s.", arg); - else - error ("No breakpoint at this line."); - } - - if (found->next) from_tty = 1; /* Always report if deleted more than one */ - if (from_tty) printf_unfiltered ("Deleted breakpoint%s ", found->next ? "s" : ""); - breakpoints_changed (); - while (found) - { - if (from_tty) printf_unfiltered ("%d ", found->number); - b1 = found->next; - delete_breakpoint (found); - found = b1; - } - if (from_tty) putchar_unfiltered ('\n'); - } - free ((PTR)sals.sals); -} - -/* Delete breakpoint in BS if they are `delete' breakpoints. - This is called after any breakpoint is hit, or after errors. */ - -void -breakpoint_auto_delete (bs) - bpstat bs; -{ - for (; bs; bs = bs->next) - if (bs->breakpoint_at && bs->breakpoint_at->disposition == delete - && bs->stop) - delete_breakpoint (bs->breakpoint_at); -} - -/* Delete a breakpoint and clean up all traces of it in the data structures. */ - -void -delete_breakpoint (bpt) - struct breakpoint *bpt; -{ - register struct breakpoint *b; - register bpstat bs; - - if (bpt->inserted) - remove_breakpoint (bpt); - - if (breakpoint_chain == bpt) - breakpoint_chain = bpt->next; - - ALL_BREAKPOINTS (b) - if (b->next == bpt) - { - b->next = bpt->next; - break; - } - - check_duplicates (bpt->address); - /* 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) - { - ALL_BREAKPOINTS (b) - if (b->address == bpt->address - && !b->duplicate - && b->enable != disabled) - { - int val; - val = target_insert_breakpoint (b->address, b->shadow_contents); - if (val != 0) - { - target_terminal_ours_for_output (); - fprintf_unfiltered (gdb_stderr, "Cannot insert breakpoint %d:\n", b->number); - memory_error (val, b->address); /* which bombs us out */ - } - else - b->inserted = 1; - } - } - - free_command_lines (&bpt->commands); - if (bpt->cond) - free (bpt->cond); - if (bpt->cond_string != NULL) - free (bpt->cond_string); - if (bpt->addr_string != NULL) - free (bpt->addr_string); - if (bpt->exp_string != NULL) - free (bpt->exp_string); - if (bpt->source_file != NULL) - free (bpt->source_file); - - breakpoints_changed (); - - /* 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; - free ((PTR)bpt); -} - -static void -delete_command (arg, from_tty) - char *arg; - int from_tty; -{ - - if (arg == 0) - { - /* Ask user only if there are some breakpoints to delete. */ - if (!from_tty - || (breakpoint_chain && query ("Delete all breakpoints? ", 0, 0))) - { - /* No arg; clear all breakpoints. */ - while (breakpoint_chain) - delete_breakpoint (breakpoint_chain); - } - } - else - map_breakpoint_numbers (arg, delete_breakpoint); -} - -/* Reset a breakpoint given it's struct breakpoint * BINT. - The value we return ends up being the return value from catch_errors. - Unused in this case. */ - -static int -breakpoint_re_set_one (bint) - char *bint; -{ - struct breakpoint *b = (struct breakpoint *)bint; /* get past catch_errs */ - struct value *mark; - int i; - struct symtabs_and_lines sals; - char *s; - enum enable save_enable; - - switch (b->type) - { - case bp_breakpoint: - case bp_hardware_breakpoint: - if (b->addr_string == NULL) - { - /* Anything without a string can't be re-set. */ - delete_breakpoint (b); - return 0; - } - /* In case we have a problem, disable this breakpoint. We'll restore - its status if we succeed. */ - save_enable = b->enable; - b->enable = disabled; - - s = b->addr_string; - sals = decode_line_1 (&s, 1, (struct symtab *)NULL, 0, (char ***)NULL); - for (i = 0; i < sals.nelts; i++) - { - resolve_sal_pc (&sals.sals[i]); - - /* Reparse conditions, they might contain references to the - old symtab. */ - if (b->cond_string != NULL) - { - s = b->cond_string; - if (b->cond) - free ((PTR)b->cond); - b->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0); - } - - /* We need to re-set the breakpoint if the address changes...*/ - if (b->address != sals.sals[i].pc - /* ...or new and old breakpoints both have source files, and - the source file name or the line number changes... */ - || (b->source_file != NULL - && sals.sals[i].symtab != NULL - && (!STREQ (b->source_file, sals.sals[i].symtab->filename) - || b->line_number != sals.sals[i].line) - ) - /* ...or we switch between having a source file and not having - one. */ - || ((b->source_file == NULL) != (sals.sals[i].symtab == NULL)) - ) - { - if (b->source_file != NULL) - free (b->source_file); - if (sals.sals[i].symtab == NULL) - b->source_file = NULL; - else - b->source_file = - savestring (sals.sals[i].symtab->filename, - strlen (sals.sals[i].symtab->filename)); - b->line_number = sals.sals[i].line; - b->address = sals.sals[i].pc; - - check_duplicates (b->address); - - mention (b); - - /* Might be better to do this just once per breakpoint_re_set, - rather than once for every breakpoint. */ - breakpoints_changed (); - } - b->enable = save_enable; /* Restore it, this worked. */ - } - free ((PTR)sals.sals); - break; - - case bp_watchpoint: - case bp_hardware_watchpoint: - case bp_read_watchpoint: - case bp_access_watchpoint: - innermost_block = NULL; - /* The issue arises of what context to evaluate this in. The same - one as when it was set, but what does that mean when symbols have - been re-read? We could save the filename and functionname, but - if the context is more local than that, the best we could do would - be something like how many levels deep and which index at that - particular level, but that's going to be less stable than filenames - or functionnames. */ - /* So for now, just use a global context. */ - b->exp = parse_expression (b->exp_string); - b->exp_valid_block = innermost_block; - mark = value_mark (); - b->val = evaluate_expression (b->exp); - release_value (b->val); - if (VALUE_LAZY (b->val)) - value_fetch_lazy (b->val); - - if (b->cond_string != NULL) - { - s = b->cond_string; - b->cond = parse_exp_1 (&s, (struct block *)0, 0); - } - if (b->enable == enabled) - mention (b); - value_free_to_mark (mark); - break; - - default: - printf_filtered ("Deleting unknown breakpoint type %d\n", b->type); - /* fall through */ - case bp_until: - case bp_finish: - case bp_longjmp: - case bp_longjmp_resume: - case bp_watchpoint_scope: - case bp_call_dummy: - delete_breakpoint (b); - break; - } - - return 0; -} - -/* Re-set all breakpoints after symbols have been re-loaded. */ -void -breakpoint_re_set () -{ - struct breakpoint *b, *temp; - static char message1[] = "Error in re-setting breakpoint %d:\n"; - char message[sizeof (message1) + 30 /* slop */]; - - 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); - } - - create_longjmp_breakpoint("longjmp"); - create_longjmp_breakpoint("_longjmp"); - create_longjmp_breakpoint("siglongjmp"); - create_longjmp_breakpoint(NULL); - -#if 0 - /* Took this out (temporaliy at least), since it produces an extra - blank line at startup. This messes up the gdbtests. -PB */ - /* Blank line to finish off all those mention() messages we just printed. */ - printf_filtered ("\n"); -#endif -} - -/* Set ignore-count of breakpoint number BPTNUM to COUNT. - If from_tty is nonzero, it prints a message to that effect, - which ends with a period (no newline). */ - -void -set_ignore_count (bptnum, count, from_tty) - int bptnum, count, from_tty; -{ - register struct breakpoint *b; - - if (count < 0) - count = 0; - - ALL_BREAKPOINTS (b) - if (b->number == bptnum) - { - b->ignore_count = count; - if (!from_tty) - return; - else if (count == 0) - printf_filtered ("Will stop next time breakpoint %d is reached.", - bptnum); - else if (count == 1) - printf_filtered ("Will ignore next crossing of breakpoint %d.", - bptnum); - else - printf_filtered ("Will ignore next %d crossings of breakpoint %d.", - count, bptnum); - breakpoints_changed (); - return; - } - - error ("No breakpoint number %d.", bptnum); -} - -/* Clear the ignore counts of all breakpoints. */ -void -breakpoint_clear_ignore_counts () -{ - struct breakpoint *b; - - ALL_BREAKPOINTS (b) - b->ignore_count = 0; -} - -/* Command to set ignore-count of breakpoint N to COUNT. */ - -static void -ignore_command (args, from_tty) - char *args; - int from_tty; -{ - char *p = args; - register int num; - - if (p == 0) - error_no_arg ("a breakpoint number"); - - num = get_number (&p); - - if (*p == 0) - error ("Second argument (specified ignore-count) is missing."); - - set_ignore_count (num, - longest_to_int (value_as_long (parse_and_eval (p))), - from_tty); - printf_filtered ("\n"); - breakpoints_changed (); -} - -/* Call FUNCTION on each of the breakpoints - whose numbers are given in ARGS. */ - -static void -map_breakpoint_numbers (args, function) - char *args; - void (*function) PARAMS ((struct breakpoint *)); -{ - register char *p = args; - char *p1; - register int num; - register struct breakpoint *b; - - if (p == 0) - error_no_arg ("one or more breakpoint numbers"); - - while (*p) - { - p1 = p; - - num = get_number (&p1); - - ALL_BREAKPOINTS (b) - if (b->number == num) - { - struct breakpoint *related_breakpoint = b->related_breakpoint; - function (b); - if (related_breakpoint) - function (related_breakpoint); - goto win; - } - printf_unfiltered ("No breakpoint number %d.\n", num); - win: - p = p1; - } -} - -static void -enable_breakpoint (bpt) - struct breakpoint *bpt; -{ - FRAME 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; - breakpoints_changed (); - 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) - { - FRAME 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); - } -} - -/* 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); -} - -static void -disable_breakpoint (bpt) - struct breakpoint *bpt; -{ - /* Never disable a watchpoint scope breakpoint; we want to - hit them when we leave scope so we can delete both the - watchpoint and its scope breakpoint at that time. */ - if (bpt->type == bp_watchpoint_scope) - return; - - bpt->enable = disabled; - - breakpoints_changed (); - - check_duplicates (bpt->address); -} - -/* ARGSUSED */ -static void -disable_command (args, from_tty) - char *args; - int from_tty; -{ - register 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: - disable_breakpoint (bpt); - default: - continue; - } - else - map_breakpoint_numbers (args, disable_breakpoint); -} - -static void -enable_once_breakpoint (bpt) - struct breakpoint *bpt; -{ - FRAME 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; - bpt->disposition = disable; - check_duplicates (bpt->address); - breakpoints_changed (); - - 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) - { - FRAME 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); - } - } - - if (save_selected_frame_level >= 0) - select_frame (save_selected_frame, save_selected_frame_level); - value_free_to_mark (mark); - } -} - -/* ARGSUSED */ -static void -enable_once_command (args, from_tty) - char *args; - int from_tty; -{ - map_breakpoint_numbers (args, enable_once_breakpoint); -} - -static void -enable_delete_breakpoint (bpt) - struct breakpoint *bpt; -{ - bpt->enable = enabled; - bpt->disposition = delete; - - check_duplicates (bpt->address); - breakpoints_changed (); -} - -/* ARGSUSED */ -static void -enable_delete_command (args, from_tty) - char *args; - int from_tty; -{ - map_breakpoint_numbers (args, enable_delete_breakpoint); -} - -/* - * Use default_breakpoint_'s, or nothing if they aren't valid. - */ -struct symtabs_and_lines -decode_line_spec_1 (string, funfirstline) - char *string; - int funfirstline; -{ - struct symtabs_and_lines sals; - if (string == 0) - error ("Empty line specification."); - if (default_breakpoint_valid) - sals = decode_line_1 (&string, funfirstline, - default_breakpoint_symtab, default_breakpoint_line, - (char ***)NULL); - else - sals = decode_line_1 (&string, funfirstline, - (struct symtab *)NULL, 0, (char ***)NULL); - if (*string) - error ("Junk at end of line specification: %s", string); - return sals; -} - -void -_initialize_breakpoint () -{ - breakpoint_chain = 0; - /* Don't bother to call set_breakpoint_count. $bpnum isn't useful - before a breakpoint is set. */ - breakpoint_count = 0; - - add_com ("ignore", class_breakpoint, ignore_command, - "Set ignore-count of breakpoint number N to COUNT.\n\ -Usage is `ignore N COUNT'."); - - add_com ("commands", class_breakpoint, commands_command, - "Set commands to be executed when a breakpoint is hit.\n\ -Give breakpoint number as argument after \"commands\".\n\ -With no argument, the targeted breakpoint is the last one set.\n\ -The commands themselves follow starting on the next line.\n\ -Type a line containing \"end\" to indicate the end of them.\n\ -Give \"silent\" as the first line to make the breakpoint silent;\n\ -then no output is printed when it is hit, except what the commands print."); - - add_com ("condition", class_breakpoint, condition_command, - "Specify breakpoint number N to break only if COND is true.\n\ -Usage is `condition N COND', where N is an integer and COND is an\n\ -expression to be evaluated whenever breakpoint N is reached. "); - - add_com ("tbreak", class_breakpoint, tbreak_command, - "Set a temporary breakpoint. Args like \"break\" command.\n\ -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 ("hbreak", class_breakpoint, hbreak_command, - "Set a hardware assisted breakpoint. Args like \"break\" command.\n\ -Like \"break\" except the breakpoint requires hardware support,\n\ -some target hardware may not have this support."); - - add_com ("thbreak", class_breakpoint, thbreak_command, - "Set a temporary hardware assisted breakpoint. Args like \"break\" command.\n\ -Like \"hbreak\" except the breakpoint is only temporary,\n\ -so it will be deleted when hit."); - - add_prefix_cmd ("enable", 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.", - &enablelist, "enable ", 1, &cmdlist); - - add_abbrev_prefix_cmd ("breakpoints", class_breakpoint, enable_command, - "Enable some breakpoints.\n\ -Give breakpoint numbers (separated by spaces) as arguments.\n\ -This is used to cancel the effect of the \"disable\" command.\n\ -May be abbreviated to simply \"enable\".\n", - &enablebreaklist, "enable breakpoints ", 1, &enablelist); - - add_cmd ("once", no_class, enable_once_command, - "Enable breakpoints for one hit. Give breakpoint numbers.\n\ -If a breakpoint is hit while enabled in this fashion, it becomes disabled.", - &enablebreaklist); - - add_cmd ("delete", no_class, enable_delete_command, - "Enable breakpoints and delete when hit. Give breakpoint numbers.\n\ -If a breakpoint is hit while enabled in this fashion, it is deleted.", - &enablebreaklist); - - add_cmd ("delete", no_class, enable_delete_command, - "Enable breakpoints and delete when hit. Give breakpoint numbers.\n\ -If a breakpoint is hit while enabled in this fashion, it is deleted.", - &enablelist); - - add_cmd ("once", no_class, enable_once_command, - "Enable breakpoints for one hit. Give breakpoint numbers.\n\ -If a breakpoint is hit while enabled in this fashion, it becomes disabled.", - &enablelist); - - add_prefix_cmd ("disable", 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.", - &disablelist, "disable ", 1, &cmdlist); - add_com_alias ("dis", "disable", class_breakpoint, 1); - add_com_alias ("disa", "disable", class_breakpoint, 1); - - add_cmd ("breakpoints", class_alias, 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.\n\ -This command may be abbreviated \"disable\".", - &disablelist); - - add_prefix_cmd ("delete", class_breakpoint, delete_command, - "Delete some breakpoints or auto-display expressions.\n\ -Arguments are breakpoint numbers with spaces in between.\n\ -To delete all breakpoints, give no argument.\n\ -\n\ -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); - - add_cmd ("breakpoints", class_alias, delete_command, - "Delete some breakpoints or auto-display expressions.\n\ -Arguments are breakpoint numbers with spaces in between.\n\ -To delete all breakpoints, give no argument.\n\ -This command may be abbreviated \"delete\".", - &deletelist); - - add_com ("clear", class_breakpoint, clear_command, - "Clear breakpoint at specified line or function.\n\ -Argument may be line number, function name, or \"*\" and an address.\n\ -If line number is specified, all breakpoints in that line are cleared.\n\ -If function is specified, breakpoints at beginning of function are cleared.\n\ -If an address is specified, breakpoints at that address are cleared.\n\n\ -With no argument, clears all breakpoints in the line that the selected frame\n\ -is executing in.\n\ -\n\ -See also the \"delete\" command which clears breakpoints by number."); - - add_com ("break", class_breakpoint, break_command, - "Set breakpoint at specified line or function.\n\ -Argument may be line number, function name, or \"*\" and an address.\n\ -If line number is specified, break at start of code for that line.\n\ -If function is specified, break at start of code for that function.\n\ -If an address is specified, break at 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."); - add_com_alias ("b", "break", class_run, 1); - add_com_alias ("br", "break", class_run, 1); - add_com_alias ("bre", "break", class_run, 1); - add_com_alias ("brea", "break", class_run, 1); - - add_info ("breakpoints", breakpoints_info, - "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."); - -#if MAINTENANCE_CMDS - - add_cmd ("breakpoints", class_maintenance, maintenance_info_breakpoints, - "Status of all breakpoints, or breakpoint number NUMBER.\n\ -The \"Type\" column indicates one of:\n\ -\tbreakpoint - normal breakpoint\n\ -\twatchpoint - watchpoint\n\ -\tlongjmp - internal breakpoint used to step through longjmp()\n\ -\tlongjmp resume - internal breakpoint at the target of longjmp()\n\ -\tuntil - internal breakpoint used by the \"until\" command\n\ -\tfinish - internal breakpoint used by the \"finish\" command\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.", - &maintenanceinfolist); - -#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\ -\n\ -Do \"help breakpoints\" for info on other commands dealing with breakpoints."); - - 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."); - - add_com ("rwatch", class_breakpoint, rwatch_command, - "Set a read watchpoint for an expression.\n\ -A watchpoint stops execution of your program whenever the value of\n\ -an expression is read."); - - add_com ("awatch", class_breakpoint, awatch_command, - "Set a watchpoint for an expression.\n\ -A watchpoint stops execution of your program whenever the value of\n\ -an expression is either read or written."); - - add_info ("watchpoints", breakpoints_info, - "Synonym for ``info breakpoints''."); - -} - -/* OK, when we call objfile_relocate, we need to relocate breakpoints - too. breakpoint_re_set is not a good choice--for example, if - addr_string contains just a line number without a file name the - breakpoint might get set in a different file. In general, there is - no need to go all the way back to the user's string (though this might - work if some effort were made to canonicalize it), since symtabs and - everything except addresses are still valid. - - Probably the best way to solve this is to have each breakpoint save - the objfile and the section number that was used to set it (if set - by "*addr", probably it is best to use find_pc_line to get a symtab - and use the objfile and block_line_section for that symtab). Then - objfile_relocate can call fixup_breakpoints with the objfile and - the new_offsets, and it can relocate only the appropriate breakpoints. */ - -#ifdef IBM6000_TARGET -/* But for now, just kludge it based on the concept that before an - objfile is relocated the breakpoint is below 0x10000000, and afterwards - it is higher, so that way we only relocate each breakpoint once. */ - -void -fixup_breakpoints (low, high, delta) - CORE_ADDR low; - CORE_ADDR high; - CORE_ADDR delta; -{ - struct breakpoint *b; - - ALL_BREAKPOINTS (b) - { - if (b->address >= low && b->address <= high) - b->address += delta; - } -} -#endif diff --git a/gnu/usr.bin/gdb/gdb/breakpoint.h b/gnu/usr.bin/gdb/gdb/breakpoint.h deleted file mode 100644 index 8242c14..0000000 --- a/gnu/usr.bin/gdb/gdb/breakpoint.h +++ /dev/null @@ -1,419 +0,0 @@ -/* Data structures associated with breakpoints in GDB. - Copyright (C) 1992, 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. */ - -#if !defined (BREAKPOINT_H) -#define BREAKPOINT_H 1 - -#include "frame.h" -#include "value.h" - -/* This is the maximum number of bytes a breakpoint instruction can take. - Feel free to increase it. It's just used in a few places to size - arrays that should be independent of the target architecture. */ - -#define BREAKPOINT_MAX 16 - -/* Type of breakpoint. */ -/* FIXME In the future, we should fold all other breakpoint-like things into - here. This includes: - - * single-step (for machines where we have to simulate single stepping) - (probably, though perhaps it is better for it to look as much as - possible like a single-step to wait_for_inferior). */ - -enum bptype { - bp_breakpoint, /* Normal breakpoint */ - bp_hardware_breakpoint, /* Hardware assisted breakpoint */ - bp_until, /* used by until command */ - bp_finish, /* used by finish command */ - bp_watchpoint, /* Watchpoint */ - bp_hardware_watchpoint, /* Hardware assisted watchpoint */ - bp_read_watchpoint, /* read watchpoint, (hardware assisted) */ - bp_access_watchpoint, /* access watchpoint, (hardware assisted) */ - bp_longjmp, /* secret breakpoint to find longjmp() */ - bp_longjmp_resume, /* secret breakpoint to escape longjmp() */ - - /* Used by wait_for_inferior for stepping over subroutine calls, for - stepping over signal handlers, and for skipping prologues. */ - bp_step_resume, - - /* Used by wait_for_inferior for stepping over signal handlers. */ - bp_through_sigtramp, - - /* Used to detect when a watchpoint expression has gone out of - scope. These breakpoints are usually not visible to the user. - - This breakpoint has some interesting properties: - - 1) There's always a 1:1 mapping between watchpoints - on local variables and watchpoint_scope breakpoints. - - 2) It automatically deletes itself and the watchpoint it's - associated with when hit. - - 3) It can never be disabled. */ - bp_watchpoint_scope, - - /* The breakpoint at the end of a call dummy. */ - /* FIXME: What if the function we are calling longjmp()s out of the - call, or the user gets out with the "return" command? We currently - have no way of cleaning up the breakpoint in these (obscure) situations. - (Probably can solve this by noticing longjmp, "return", etc., it's - similar to noticing when a watchpoint on a local variable goes out - of scope (with hardware support for watchpoints)). */ - bp_call_dummy -}; - -/* States of enablement of breakpoint. */ - -enum enable { disabled, enabled}; - -/* Disposition of breakpoint. Ie: what to do after hitting it. */ - -enum bpdisp { - delete, /* Delete it */ - disable, /* Disable it */ - donttouch /* Leave it alone */ -}; - -/* Note that the ->silent field is not currently used by any commands - (though the code is in there if it was to be, and set_raw_breakpoint - does set it to 0). I implemented it because I thought it would be - useful for a hack I had to put in; I'm going to leave it in because - I can see how there might be times when it would indeed be useful */ - -/* This is for a breakpoint or a watchpoint. */ - -struct breakpoint -{ - struct breakpoint *next; - /* Type of breakpoint. */ - enum bptype type; - /* Zero means disabled; remember the info but don't break here. */ - enum enable enable; - /* What to do with this breakpoint after we hit it. */ - enum bpdisp disposition; - /* Number assigned to distinguish breakpoints. */ - int number; - - /* Address to break at, or NULL if not a breakpoint. */ - 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; - - /* Non-zero means a silent breakpoint (don't print frame info - if we stop here). */ - unsigned char silent; - /* Number of stops at this breakpoint that should - be continued automatically before really stopping. */ - int ignore_count; - /* "Real" contents of byte where breakpoint has been inserted. - Valid only when breakpoints are in the program. Under the complete - control of the target insert_breakpoint and remove_breakpoint routines. - No other code should assume anything about the value(s) here. */ - char shadow_contents[BREAKPOINT_MAX]; - /* Nonzero if this breakpoint is now inserted. Only matters if address - is non-NULL. */ - char inserted; - /* Nonzero if this is not the first breakpoint in the list - for the given address. Only matters if address is non-NULL. */ - char duplicate; - /* Chain of command lines to execute when this breakpoint is hit. */ - struct command_line *commands; - /* Stack depth (address of frame). If nonzero, break only if fp - equals this. */ - FRAME_ADDR frame; - /* Conditional. Break only if this expression's value is nonzero. */ - struct expression *cond; - - /* String we used to set the breakpoint (malloc'd). Only matters if - address is non-NULL. */ - char *addr_string; - /* String form of the breakpoint condition (malloc'd), or NULL if there - is no condition. */ - char *cond_string; - /* String form of exp (malloc'd), or NULL if none. */ - char *exp_string; - - /* The expression we are watching, or NULL if not a watchpoint. */ - struct expression *exp; - /* The largest block within which it is valid, or NULL if it is - valid anywhere (e.g. consists just of global symbols). */ - struct block *exp_valid_block; - /* Value of the watchpoint the last time we checked it. */ - value_ptr val; - - /* Holds the value chain for a hardware watchpoint expression. */ - value_ptr val_chain; - - /* Holds the address of the related watchpoint_scope breakpoint - when using watchpoints on local variables (might the concept - of a related breakpoint be useful elsewhere, if not just call - it the watchpoint_scope breakpoint or something like that. FIXME). */ - struct breakpoint *related_breakpoint; - - /* Holds the frame address which identifies the frame this watchpoint - should be evaluated in, or NULL if the watchpoint should be evaluated - on the outermost frame. */ - FRAME_ADDR watchpoint_frame; - - /* Thread number for thread-specific breakpoint, or -1 if don't care */ - int thread; - - /* Count of the number of times this breakpoint was taken, dumped - with the info, but not used for anything else. Useful for - seeing how many times you hit a break prior to the program - aborting, so you can back up to just before the abort. */ - int hit_count; - -}; - -/* The following stuff is an abstract data type "bpstat" ("breakpoint status"). - This provides the ability to determine whether we have stopped at a - breakpoint, and what we should do about it. */ - -typedef struct bpstat *bpstat; - -/* Interface: */ -/* Clear a bpstat so that it says we are not at any breakpoint. - Also free any storage that is part of a bpstat. */ -extern void bpstat_clear PARAMS ((bpstat *)); - -/* Return a copy of a bpstat. Like "bs1 = bs2" but all storage that - is part of the bpstat is copied as well. */ -extern bpstat bpstat_copy PARAMS ((bpstat)); - -/* FIXME: prototypes uses equivalence between FRAME_ADDR and CORE_ADDR */ -extern bpstat bpstat_stop_status PARAMS ((CORE_ADDR *, CORE_ADDR, int)); - -/* This bpstat_what stuff tells wait_for_inferior what to do with a - breakpoint (a challenging task). */ - -enum bpstat_what_main_action { - /* Perform various other tests; that is, this bpstat does not - say to perform any action (e.g. failed watchpoint and nothing - else). */ - BPSTAT_WHAT_KEEP_CHECKING, - - /* Rather than distinguish between noisy and silent stops here, it - might be cleaner to have bpstat_print make that decision (also - taking into account stop_print_frame and source_only). But the - implications are a bit scary (interaction with auto-displays, etc.), - so I won't try it. */ - - /* Stop silently. */ - BPSTAT_WHAT_STOP_SILENT, - - /* Stop and print. */ - BPSTAT_WHAT_STOP_NOISY, - - /* Remove breakpoints, single step once, then put them back in and - go back to what we were doing. It's possible that this should be - removed from the main_action and put into a separate field, to more - cleanly handle BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE. */ - BPSTAT_WHAT_SINGLE, - - /* Set longjmp_resume breakpoint, remove all other breakpoints, - and continue. The "remove all other breakpoints" part is required - if we are also stepping over another breakpoint as well as doing - the longjmp handling. */ - BPSTAT_WHAT_SET_LONGJMP_RESUME, - - /* Clear longjmp_resume breakpoint, then handle as - BPSTAT_WHAT_KEEP_CHECKING. */ - BPSTAT_WHAT_CLEAR_LONGJMP_RESUME, - - /* Clear longjmp_resume breakpoint, then handle as BPSTAT_WHAT_SINGLE. */ - BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE, - - /* Clear step resume breakpoint, and keep checking. */ - BPSTAT_WHAT_STEP_RESUME, - - /* Clear through_sigtramp breakpoint, muck with trap_expected, and keep - checking. */ - BPSTAT_WHAT_THROUGH_SIGTRAMP, - - /* This is just used to keep track of how many enums there are. */ - BPSTAT_WHAT_LAST -}; - -struct bpstat_what { - enum bpstat_what_main_action main_action; - - /* Did we hit a call dummy breakpoint? This only goes with a main_action - of BPSTAT_WHAT_STOP_SILENT or BPSTAT_WHAT_STOP_NOISY (the concept of - continuing from a call dummy without popping the frame is not a - useful one). */ - int call_dummy; -}; - -/* Tell what to do about this bpstat. */ -struct bpstat_what bpstat_what PARAMS ((bpstat)); - -/* Find the bpstat associated with a breakpoint. NULL otherwise. */ -bpstat bpstat_find_breakpoint PARAMS ((bpstat, struct breakpoint *)); - -/* 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 - a watchpoint enabled. */ -#define bpstat_explains_signal(bs) ((bs) != NULL) - -/* Nonzero if we should step constantly (e.g. watchpoints on machines - without hardware support). This isn't related to a specific bpstat, - just to things like whether watchpoints are set. */ -extern int bpstat_should_step 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). */ -extern int bpstat_print PARAMS ((bpstat)); - -/* 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 - anything but further calls to bpstat_num). - Return 0 if passed a bpstat which does not indicate any breakpoints. */ -extern int bpstat_num PARAMS ((bpstat *)); - -/* Perform actions associated with having stopped at *BSP. Actually, we just - use this for breakpoint commands. Perhaps other actions will go here - later, but this is executed at a late time (from the command loop). */ -extern void bpstat_do_actions PARAMS ((bpstat *)); - -/* Modify BS so that the actions will not be performed. */ -extern void bpstat_clear_actions PARAMS ((bpstat)); - -/* Implementation: */ -struct bpstat -{ - /* Linked list because there can be two breakpoints at the - same place, and a bpstat reflects the fact that both have been hit. */ - bpstat next; - /* Breakpoint that we are at. */ - struct breakpoint *breakpoint_at; - /* Commands left to be done. */ - struct command_line *commands; - /* Old value associated with a watchpoint. */ - value_ptr old_val; - - /* Nonzero if this breakpoint tells us to print the frame. */ - char print; - - /* Nonzero if this breakpoint tells us to stop. */ - char stop; - - /* Function called by bpstat_print to print stuff associated with - this element of the bpstat chain. Returns 0 or 1 just like - bpstat_print, or -1 if it can't deal with it. */ - int (*print_it) PARAMS((bpstat bs)); -}; - -/* Prototypes for breakpoint-related functions. */ - -#ifdef __STDC__ /* Forward declarations for prototypes */ -struct frame_info; -#endif - -extern int breakpoint_here_p PARAMS ((CORE_ADDR)); - -extern int frame_in_dummy PARAMS ((struct frame_info *)); - -extern int breakpoint_thread_match PARAMS ((CORE_ADDR, int)); - -extern void -until_break_command PARAMS ((char *, int)); - -extern void -breakpoint_re_set PARAMS ((void)); - -extern void -clear_momentary_breakpoints PARAMS ((void)); - -/* FIXME: Prototype uses equivalence of "struct frame_info *" and FRAME */ -extern struct breakpoint * -set_momentary_breakpoint PARAMS ((struct symtab_and_line, - struct frame_info *, - enum bptype)); - -extern void -set_ignore_count PARAMS ((int, int, int)); - -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 -delete_breakpoint PARAMS ((struct breakpoint *)); - -extern void -breakpoint_auto_delete PARAMS ((bpstat)); - -extern void -breakpoint_clear_ignore_counts PARAMS ((void)); - -extern void -break_command PARAMS ((char *, int)); - -extern int -insert_breakpoints PARAMS ((void)); - -extern int -remove_breakpoints PARAMS ((void)); - -extern void -enable_longjmp_breakpoint PARAMS ((void)); - -extern void -disable_longjmp_breakpoint PARAMS ((void)); - -extern void -set_longjmp_resume_breakpoint PARAMS ((CORE_ADDR, FRAME)); - -extern void clear_breakpoint_hit_counts PARAMS ((void)); - -/* The following are for displays, which aren't really breakpoints, but - here is as good a place as any for them. */ - -extern void -disable_current_display PARAMS ((void)); - -extern void -do_displays PARAMS ((void)); - -extern void -disable_display PARAMS ((int)); - -extern void -clear_displays PARAMS ((void)); - -#endif /* !defined (BREAKPOINT_H) */ diff --git a/gnu/usr.bin/gdb/gdb/buildsym.c b/gnu/usr.bin/gdb/gdb/buildsym.c deleted file mode 100644 index 27f5634..0000000 --- a/gnu/usr.bin/gdb/gdb/buildsym.c +++ /dev/null @@ -1,964 +0,0 @@ -/* Support routines for building symbol tables in GDB's internal format. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992 - 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. */ - -/* This module provides subroutines used for creating and adding to - the symbol table. These routines are called from various symbol- - file-reading routines. - - Routines to support specific debugging information formats (stabs, - DWARF, etc) belong somewhere else. */ - -#include "defs.h" -#include "bfd.h" -#include "obstack.h" -#include "symtab.h" -#include "symfile.h" /* Needed for "struct complaint" */ -#include "objfiles.h" -#include "complaints.h" -#include - -/* Ask buildsym.h to define the vars it normally declares `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 *)); - -static struct blockvector * -make_blockvector PARAMS ((struct objfile *)); - - -/* 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 innerblock_complaint = - {"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}; - - -/* 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; -{ - 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 (*listhead == NULL || (*listhead)->nsyms == PENDINGSIZE) - { - if (free_pendings) - { - link = free_pendings; - free_pendings = link->next; - } - else - { - link = (struct pending *) xmalloc (sizeof (struct pending)); - } - - link->next = *listhead; - *listhead = link; - link->nsyms = 0; - } - - (*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. */ - -struct symbol * -find_symbol_in_list (list, name, length) - struct pending *list; - char *name; - int length; -{ - int j; - char *pp; - - while (list != NULL) - { - for (j = list->nsyms; --j >= 0; ) - { - pp = SYMBOL_NAME (list->symbol[j]); - if (*pp == *name && strncmp (pp, name, length) == 0 && - pp[length] == '\0') - { - return (list->symbol[j]); - } - } - list = list->next; - } - return (NULL); -} - -/* 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; -{ - 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_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; - - for (next = file_symbols; next != NULL; next = next1) - { - next1 = next->next; - free ((PTR)next); - } - file_symbols = NULL; - - for (next = global_symbols; next != NULL; next = next1) - { - next1 = next->next; - free ((PTR)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. */ - -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; -{ - register struct pending *next, *next1; - register struct block *block; - register struct pending_block *pblock; - struct pending_block *opblock; - register int i; - register int j; - - /* Count the length of the list of symbols. */ - - for (next = *listhead, i = 0; - next; - i += next->nsyms, next = next->next) - { - /*EMPTY*/; - } - - block = (struct block *) obstack_alloc (&objfile -> symbol_obstack, - (sizeof (struct block) + ((i - 1) * sizeof (struct symbol *)))); - - /* Copy the symbols into the block. */ - - BLOCK_NSYMS (block) = i; - for (next = *listhead; next; next = next->next) - { - for (j = next->nsyms - 1; j >= 0; j--) - { - BLOCK_SYM (block, --i) = next->symbol[j]; - } - } - - BLOCK_START (block) = start; - BLOCK_END (block) = end; - /* 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. */ - - if (symbol) - { - SYMBOL_BLOCK_VALUE (symbol) = block; - BLOCK_FUNCTION (block) = symbol; - } - else - { - BLOCK_FUNCTION (block) = NULL; - } - - /* Now "free" the links of the list, and empty the list. */ - - for (next = *listhead; next; next = next1) - { - next1 = next->next; - next->next = free_pendings; - free_pendings = next; - } - *listhead = NULL; - - /* 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) - { - 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. */ - if (BLOCK_START (pblock->block) < BLOCK_START (block) || - BLOCK_END (pblock->block) > BLOCK_END (block)) - { - if (symbol) - { - complain (&innerblock_complaint, - SYMBOL_SOURCE_NAME (symbol)); - } - else - { - complain (&innerblock_anon_complaint); - } - BLOCK_START (pblock->block) = BLOCK_START (block); - BLOCK_END (pblock->block) = BLOCK_END (block); - } -#endif - BLOCK_SUPERBLOCK (pblock->block) = block; - } - 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. */ - - /* 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)); - pblock->block = block; - if (opblock) - { - pblock->next = opblock->next; - opblock->next = pblock; - } - else - { - pblock->next = pending_blocks; - pending_blocks = pblock; - } -} - -static struct blockvector * -make_blockvector (objfile) - struct objfile *objfile; -{ - register struct pending_block *next; - register struct blockvector *blockvector; - register int i; - - /* Count the length of the list of blocks. */ - - for (next = pending_blocks, i = 0; next; next = next->next, i++) {;} - - blockvector = (struct blockvector *) - 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. */ - - BLOCKVECTOR_NBLOCKS (blockvector) = i; - for (next = pending_blocks; next; next = next->next) - { - BLOCKVECTOR_BLOCK (blockvector, --i) = next->block; - } - -#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) - { - next1 = next->next; - free (next); - } -#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 (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))) - { - - /* 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))); - } - } - } -#endif - - 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). */ - -void -start_subfile (name, dirname) - char *name; - char *dirname; -{ - register struct subfile *subfile; - - /* See if this subfile is already known as a subfile of the - current main source file. */ - - for (subfile = subfiles; subfile; subfile = subfile->next) - { - if (STREQ (subfile->name, name)) - { - current_subfile = subfile; - return; - } - } - - /* 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; - subfiles = subfile; - current_subfile = subfile; - - /* Save its name and compilation directory name */ - 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. */ - - subfile->language = deduce_language_from_filename (subfile->name); - if (subfile->language == language_unknown && - subfile->next != NULL) - { - subfile->language = subfile->next->language; - } - - /* 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). */ - - if (subfile->name) - { - struct subfile *s; - - if (deduce_language_from_filename (subfile->name) == language_cplus) - for (s = subfiles; s != NULL; s = s->next) - if (s->language == language_c) - s->language = language_cplus; - } - - /* And patch up this file if necessary. */ - if (subfile->language == language_c - && subfile->next != NULL - && subfile->next->language == language_cplus) - { - subfile->language = language_cplus; - } -} - -/* 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 '/'). */ - -void -patch_subfile_names (subfile, name) - struct subfile *subfile; - char *name; -{ - if (subfile != NULL && subfile->dirname == NULL && subfile->name != NULL - && subfile->name[strlen(subfile->name)-1] == '/') - { - subfile->dirname = subfile->name; - subfile->name = savestring (name, strlen (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. */ - - subfile->language = deduce_language_from_filename (subfile->name); - if (subfile->language == language_unknown && - subfile->next != NULL) - { - subfile->language = subfile->next->language; - } - } -} - - -/* 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 () -{ - register struct subfile_stack *tem - = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack)); - - tem->next = subfile_stack; - subfile_stack = tem; - if (current_subfile == NULL || current_subfile->name == NULL) - { - abort (); - } - tem->name = current_subfile->name; -} - -char * -pop_subfile () -{ - register char *name; - register struct subfile_stack *link = subfile_stack; - - if (link == NULL) - { - abort (); - } - name = link->name; - subfile_stack = link->next; - free ((PTR)link); - return (name); -} - - -/* 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; -{ - struct linetable_entry *e; - /* Ignore the dummy line number in libg.o */ - - if (line == 0xffff) - { - return; - } - - /* Make sure line vector exists and is big enough. */ - if (!subfile->line_vector) - { - 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->nitems = 0; - } - - 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))); - } - - e = subfile->line_vector->item + subfile->line_vector->nitems++; - 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; -{ - struct linetable_entry *ln1 = (struct linetable_entry *) ln1p; - struct linetable_entry *ln2 = (struct linetable_entry *) ln2p; - - /* Note: this code does not assume that CORE_ADDRs can fit in ints. - Please keep it that way. */ - if (ln1->pc < ln2->pc) - return -1; - - if (ln1->pc > ln2->pc) - return 1; - - /* If pc equal, sort by line. I'm not sure whether this is optimum - 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. */ - -void -start_symtab (name, dirname, start_addr) - char *name; - char *dirname; - CORE_ADDR start_addr; -{ - - last_source_file = name; - last_source_start_addr = start_addr; - file_symbols = NULL; - global_symbols = NULL; - within_function = 0; - - /* 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; - context_stack = (struct context_stack *) - xmalloc (context_stack_size * sizeof (struct context_stack)); - } - context_stack_depth = 0; - - /* 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. - - 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). */ - -struct symtab * -end_symtab (end_addr, sort_pending, sort_linevec, objfile, section) - CORE_ADDR end_addr; - int sort_pending; - int sort_linevec; - struct objfile *objfile; - int section; -{ - register struct symtab *symtab = NULL; - register struct blockvector *blockvector; - register struct subfile *subfile; - register struct context_stack *cstk; - struct subfile *nextsub; - - /* 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]; - /* 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(). */ - static struct complaint msg = - {"Context stack not empty in end_symtab", 0, 0}; - complain (&msg); - context_stack_depth = 0; - } - } - - /* It is unfortunate that in xcoff, pending blocks might not be ordered - in this stage. Especially, blocks for static functions will show up at - the end. We need to sort them, so tools like `find_pc_function' and - `find_pc_block' can work reliably. */ - - if (sort_pending && pending_blocks) - { - /* FIXME! Remove this horrid bubble sort and use qsort!!! */ - int swapped; - do - { - struct pending_block *pb, *pbnext; - - pb = pending_blocks; - pbnext = pb->next; - swapped = 0; - - while (pbnext) - { - /* swap blocks if unordered! */ - - if (BLOCK_START(pb->block) < BLOCK_START(pbnext->block)) - { - struct block *tmp = pb->block; - pb->block = pbnext->block; - pbnext->block = tmp; - swapped = 1; - } - pb = pbnext; - pbnext = pbnext->next; - } - } 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 - are no-ops. FIXME: Is this handled right in case of QUIT? Can - we make this cleaner? */ - - cleanup_undefined_types (); - finish_global_stabs (objfile); - - if (pending_blocks == NULL - && file_symbols == NULL - && global_symbols == NULL) - { - /* Ignore symtabs that have no functions with real debugging info */ - blockvector = NULL; - } - else - { - /* 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, - objfile); - blockvector = make_blockvector (objfile); - } - -#ifdef PROCESS_LINENUMBER_HOOK - PROCESS_LINENUMBER_HOOK (); /* Needed for xcoff. */ -#endif - - /* Now create the symtab objects proper, one for each subfile. */ - /* (The main file is the last one on the chain.) */ - - 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 (blockvector) - { - if (subfile->line_vector) - { - linetablesize = sizeof (struct linetable) + - 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. */ - /* First, shrink the linetable to make more memory. */ - subfile->line_vector = (struct linetable *) - xrealloc ((char *) subfile->line_vector, linetablesize); -#endif - /* If sort_linevec is false, we might want just check to make - sure they are sorted and complain() if not, as a way of - tracking down compilers/symbol readers which don't get - them sorted right. */ - - if (sort_linevec) - qsort (subfile->line_vector->item, - subfile->line_vector->nitems, - sizeof (struct linetable_entry), compare_line_numbers); - } - - /* Now, allocate a symbol table. */ - symtab = allocate_symtab (subfile->name, objfile); - - /* Fill in its components. */ - symtab->blockvector = blockvector; - if (subfile->line_vector) - { - /* Reallocate the line table on the symbol obstack */ - symtab->linetable = (struct linetable *) - obstack_alloc (&objfile -> symbol_obstack, linetablesize); - memcpy (symtab->linetable, subfile->line_vector, linetablesize); - } - else - { - symtab->linetable = NULL; - } - symtab->block_line_section = section; - if (subfile->dirname) - { - /* Reallocate the dirname on the symbol obstack */ - symtab->dirname = (char *) - obstack_alloc (&objfile -> symbol_obstack, - strlen (subfile -> dirname) + 1); - strcpy (symtab->dirname, subfile->dirname); - } - else - { - symtab->dirname = NULL; - } - 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. */ - symtab->language = subfile->language; - - /* All symtabs for the main file and the subfiles share a - blockvector, so we need to clear primary for everything but - the main file. */ - - symtab->primary = 0; - } - if (subfile->name != NULL) - { - free ((PTR) subfile->name); - } - if (subfile->dirname != NULL) - { - free ((PTR) subfile->dirname); - } - if (subfile->line_vector != NULL) - { - free ((PTR) subfile->line_vector); - } - - nextsub = subfile->next; - free ((PTR)subfile); - } - - /* Set this for the main source file. */ - if (symtab) - { - symtab->primary = 1; - } - - last_source_file = NULL; - current_subfile = NULL; - - 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. */ - -struct context_stack * -push_context (desc, valu) - int desc; - CORE_ADDR valu; -{ - register struct context_stack *new; - - if (context_stack_depth == context_stack_size) - { - context_stack_size *= 2; - context_stack = (struct context_stack *) - xrealloc ((char *) context_stack, - (context_stack_size * sizeof (struct context_stack))); - } - - new = &context_stack[context_stack_depth++]; - new->depth = desc; - new->locals = local_symbols; - new->old_blocks = pending_blocks; - new->start_addr = valu; - new->name = NULL; - - local_symbols = NULL; - - return (new); -} - - -/* Compute a small integer hash code for the given name. */ - -int -hashname (name) - char *name; -{ - register char *p = name; - register int total = p[0]; - register int c; - - c = p[1]; - total += c << 2; - if (c) - { - c = p[2]; - total += c << 4; - if (c) - { - total += p[3] << 6; - } - } - - /* Ensure result is positive. */ - if (total < 0) - { - total += (1000 << 6); - } - return (total % HASHSIZE); -} - - -/* 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 () -{ - free_pendings = NULL; - file_symbols = NULL; - global_symbols = NULL; - pending_blocks = NULL; -} - -/* 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). */ - -void -buildsym_new_init () -{ - buildsym_init (); -} - -/* Initializer for this module */ - -void -_initialize_buildsym () -{ -} diff --git a/gnu/usr.bin/gdb/gdb/buildsym.h b/gnu/usr.bin/gdb/gdb/buildsym.h deleted file mode 100644 index 9c69a0e..0000000 --- a/gnu/usr.bin/gdb/gdb/buildsym.h +++ /dev/null @@ -1,259 +0,0 @@ -/* Build symbol tables in GDB's internal format. - Copyright (C) 1986-1991 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 (BUILDSYM_H) -#define BUILDSYM_H 1 - -/* This module provides definitions used for creating and adding to - the symbol table. These routines are called from various symbol- - 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. */ - -#ifndef EXTERN -#define EXTERN extern -#endif - -#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. */ - -EXTERN char *last_source_file; - -/* 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. */ - -struct subfile -{ - struct subfile *next; - char *name; - char *dirname; - struct linetable *line_vector; - int line_vector_length; - enum language language; -}; - -EXTERN struct subfile *subfiles; - -EXTERN struct subfile *current_subfile; - -/* Global variable which, when set, indicates that we are processing a - .o file compiled with gcc */ - -EXTERN unsigned char processing_gcc_compilation; - -/* When set, we are processing a .o file compiled by sun acc. This is - misnamed; it refers to all stabs-in-elf implementations which use - N_UNDF the way Sun does, including Solaris gcc. Hopefully all - stabs-in-elf implementations ever invented will choose to be - compatible. */ - -EXTERN unsigned char processing_acc_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. */ - -#define PENDINGSIZE 100 - -struct pending -{ - struct pending *next; - int nsyms; - struct symbol *symbol[PENDINGSIZE]; -}; - -/* List of free `struct pending' structures for reuse. */ - -EXTERN struct pending *free_pendings; - -/* Here are the three lists that symbols are put on. */ - -EXTERN struct pending *file_symbols; /* static at top level, and types */ - -EXTERN struct pending *global_symbols; /* global functions and variables */ - -EXTERN struct pending *local_symbols; /* everything local to lexic context */ - -/* Stack representing unclosed lexical contexts - (that will become blocks, eventually). */ - -struct context_stack -{ - /* Outer locals at the time we entered */ - - struct pending *locals; - - /* Pointer into blocklist as of entry */ - - struct pending_block *old_blocks; - - /* Name of function, if any, defining context*/ - - struct symbol *name; - - /* PC where this context starts */ - - CORE_ADDR start_addr; - - /* Temp slot for exception handling. */ - - CORE_ADDR end_addr; - - /* For error-checking matching push/pop */ - - int depth; - -}; - -EXTERN struct context_stack *context_stack; - -/* Index of first unused entry in context stack. */ - -EXTERN int context_stack_depth; - -/* Currently allocated size of context stack. */ - -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. */ - -#define pop_context() (&context_stack[--context_stack_depth]); - -/* Nonzero if within a function (so symbols should be local, - if nothing says specifically). */ - -EXTERN int within_function; - -/* List of blocks already made (lexical contexts already closed). - This is used at the end to make the blockvector. */ - -struct pending_block -{ - struct pending_block *next; - struct block *block; -}; - -EXTERN struct pending_block *pending_blocks; - - -struct subfile_stack -{ - struct subfile_stack *next; - char *name; -}; - -EXTERN struct subfile_stack *subfile_stack; - -#define next_symbol_text() (*next_symbol_text_func)() - -/* Function to invoke get the next symbol. Return the symbol name. */ - -EXTERN char *(*next_symbol_text_func) PARAMS ((void)); - -/* 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.) */ - -EXTERN struct type **type_vector; - -/* Number of elements allocated for type_vector currently. */ - -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. */ - -#define INITIAL_TYPE_VECTOR_LENGTH 160 - -extern void -add_symbol_to_list PARAMS ((struct symbol *, struct pending **)); - -extern struct symbol * -find_symbol_in_list PARAMS ((struct pending *, char *, int)); - -extern void -finish_block PARAMS ((struct symbol *, struct pending **, - struct pending_block *, CORE_ADDR, CORE_ADDR, - struct objfile *)); - -extern void -really_free_pendings PARAMS ((int foo)); - -extern void -start_subfile PARAMS ((char *, char *)); - -extern void -patch_subfile_names PARAMS ((struct subfile *subfile, char *name)); - -extern void -push_subfile PARAMS ((void)); - -extern char * -pop_subfile PARAMS ((void)); - -extern struct symtab * -end_symtab PARAMS ((CORE_ADDR, int, int, struct objfile *, int)); - -extern void -scan_file_globals PARAMS ((struct objfile *)); - -extern void -buildsym_new_init PARAMS ((void)); - -extern void -buildsym_init PARAMS ((void)); - -extern struct context_stack * -push_context PARAMS ((int, CORE_ADDR)); - -extern void -record_line PARAMS ((struct subfile *, int, CORE_ADDR)); - -extern void -start_symtab PARAMS ((char *, char *, CORE_ADDR)); - -extern int -hashname PARAMS ((char *)); - -#undef EXTERN - -#endif /* defined (BUILDSYM_H) */ diff --git a/gnu/usr.bin/gdb/gdb/c-exp.y b/gnu/usr.bin/gdb/gdb/c-exp.y deleted file mode 100644 index 0e7d39a..0000000 --- a/gnu/usr.bin/gdb/gdb/c-exp.y +++ /dev/null @@ -1,1601 +0,0 @@ -/* YACC parser for C expressions, for GDB. - Copyright (C) 1986, 1989, 1990, 1991 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. */ - -/* Parse a C 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. - - 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 ( and for example) just became - too messy, particularly when such includes can be inserted at random - times by the parser generator. */ - -%{ - -#include "defs.h" -#include "expression.h" -#include "parser-defs.h" -#include "value.h" -#include "language.h" -#include "c-lang.h" - -/* 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 c_maxdepth -#define yyparse c_parse -#define yylex c_lex -#define yyerror c_error -#define yylval c_lval -#define yychar c_char -#define yydebug c_debug -#define yypact c_pact -#define yyr1 c_r1 -#define yyr2 c_r2 -#define yydef c_def -#define yychk c_chk -#define yypgo c_pgo -#define yyact c_act -#define yyexca c_exca -#define yyerrflag c_errflag -#define yynerrs c_nerrs -#define yyps c_ps -#define yypv c_pv -#define yys c_s -#define yy_yys c_yys -#define yystate c_state -#define yytmp c_tmp -#define yyv c_v -#define yy_yyv c_yyv -#define yyval c_val -#define yylloc c_lloc -#define yyreds c_reds /* With YYDEBUG defined */ -#define yytoks c_toks /* With YYDEBUG defined */ - -#ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ -#endif - -int -yyparse PARAMS ((void)); - -static int -yylex PARAMS ((void)); - -void -yyerror PARAMS ((char *)); - -%} - -/* 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; - double dval; - struct symbol *sym; - struct type *tval; - struct stoken sval; - struct ttype tsym; - struct symtoken ssym; - int voidval; - struct block *bval; - enum exp_opcode opcode; - struct internalvar *ivar; - - struct type **tvec; - int *ivec; - } - -%{ -/* YYSTYPE gets defined by %union */ -static int -parse_number PARAMS ((char *, int, int, YYSTYPE *)); -%} - -%type exp exp1 type_exp start variable qualified_name lcurly -%type rcurly -%type type typebase -%type nonempty_typelist -/* %type block */ - -/* Fancy type parsing. */ -%type func_mod direct_abs_decl abs_decl -%type ptype -%type array_mod - -%token INT -%token FLOAT - -/* Both NAME and TYPENAME tokens represent symbols in the input, - and both convey their data as strings. - But a TYPENAME is a string that happens to be defined as a typedef - or builtin type name (such as int or char) - and a NAME is any other symbol. - Contexts where this distinction is not important can use the - nonterminal "name", which matches either NAME or TYPENAME. */ - -%token STRING -%token NAME /* BLOCKNAME defined below to give it higher precedence. */ -%token TYPENAME -%type name -%type name_not_typename -%type typename - -/* 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 NAME_OR_INT - -%token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON -%token TEMPLATE -%token ERROR - -/* Special type cases, put in to allow the parser to distinguish different - legal basetypes. */ -%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD -%token LAST REGNAME - -%token VARIABLE - -%token ASSIGN_MODIFY - -/* C++ */ -%token THIS - -%left ',' -%left ABOVE_COMMA -%right '=' ASSIGN_MODIFY -%right '?' -%left OROR -%left ANDAND -%left '|' -%left '^' -%left '&' -%left EQUAL NOTEQUAL -%left '<' '>' LEQ GEQ -%left LSH RSH -%left '@' -%left '+' '-' -%left '*' '/' '%' -%right UNARY INCREMENT DECREMENT -%right ARROW '.' '[' '(' -%token BLOCKNAME -%type block -%left COLONCOLON - - -%% - -start : exp1 - | type_exp - ; - -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 : exp - | exp1 ',' exp - { write_exp_elt_opcode (BINOP_COMMA); } - ; - -/* Expressions, not including the comma operator. */ -exp : '*' exp %prec UNARY - { write_exp_elt_opcode (UNOP_IND); } - -exp : '&' exp %prec UNARY - { write_exp_elt_opcode (UNOP_ADDR); } - -exp : '-' exp %prec UNARY - { write_exp_elt_opcode (UNOP_NEG); } - ; - -exp : '!' exp %prec UNARY - { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } - ; - -exp : '~' exp %prec UNARY - { write_exp_elt_opcode (UNOP_COMPLEMENT); } - ; - -exp : INCREMENT exp %prec UNARY - { write_exp_elt_opcode (UNOP_PREINCREMENT); } - ; - -exp : DECREMENT exp %prec UNARY - { write_exp_elt_opcode (UNOP_PREDECREMENT); } - ; - -exp : exp INCREMENT %prec UNARY - { write_exp_elt_opcode (UNOP_POSTINCREMENT); } - ; - -exp : exp DECREMENT %prec UNARY - { write_exp_elt_opcode (UNOP_POSTDECREMENT); } - ; - -exp : SIZEOF exp %prec UNARY - { write_exp_elt_opcode (UNOP_SIZEOF); } - ; - -exp : exp ARROW name - { write_exp_elt_opcode (STRUCTOP_PTR); - write_exp_string ($3); - write_exp_elt_opcode (STRUCTOP_PTR); } - ; - -exp : exp ARROW qualified_name - { /* exp->type::name becomes exp->*(&type::name) */ - /* Note: this doesn't work if name is a - static member! FIXME */ - write_exp_elt_opcode (UNOP_ADDR); - write_exp_elt_opcode (STRUCTOP_MPTR); } - ; -exp : exp ARROW '*' exp - { write_exp_elt_opcode (STRUCTOP_MPTR); } - ; - -exp : exp '.' name - { write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string ($3); - 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 - static member! FIXME */ - write_exp_elt_opcode (UNOP_ADDR); - write_exp_elt_opcode (STRUCTOP_MEMBER); } - ; - -exp : exp '.' '*' exp - { write_exp_elt_opcode (STRUCTOP_MEMBER); } - ; - -exp : exp '[' exp1 ']' - { write_exp_elt_opcode (BINOP_SUBSCRIPT); } - ; - -exp : exp '(' - /* This is to save the value of arglist_len - being accumulated by an outer function call. */ - { start_arglist (); } - arglist ')' %prec ARROW - { write_exp_elt_opcode (OP_FUNCALL); - write_exp_elt_longcst ((LONGEST) end_arglist ()); - write_exp_elt_opcode (OP_FUNCALL); } - ; - -lcurly : '{' - { start_arglist (); } - ; - -arglist : - ; - -arglist : exp - { arglist_len = 1; } - ; - -arglist : arglist ',' exp %prec ABOVE_COMMA - { arglist_len++; } - ; - -rcurly : '}' - { $$ = end_arglist () - 1; } - ; -exp : lcurly arglist rcurly %prec ARROW - { write_exp_elt_opcode (OP_ARRAY); - write_exp_elt_longcst ((LONGEST) 0); - write_exp_elt_longcst ((LONGEST) $3); - write_exp_elt_opcode (OP_ARRAY); } - ; - -exp : lcurly type rcurly exp %prec UNARY - { write_exp_elt_opcode (UNOP_MEMVAL); - write_exp_elt_type ($2); - write_exp_elt_opcode (UNOP_MEMVAL); } - ; - -exp : '(' type ')' exp %prec UNARY - { write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type ($2); - write_exp_elt_opcode (UNOP_CAST); } - ; - -exp : '(' exp1 ')' - { } - ; - -/* Binary operators in order of decreasing precedence. */ - -exp : exp '@' exp - { write_exp_elt_opcode (BINOP_REPEAT); } - ; - -exp : exp '*' exp - { write_exp_elt_opcode (BINOP_MUL); } - ; - -exp : exp '/' exp - { write_exp_elt_opcode (BINOP_DIV); } - ; - -exp : exp '%' exp - { write_exp_elt_opcode (BINOP_REM); } - ; - -exp : exp '+' exp - { write_exp_elt_opcode (BINOP_ADD); } - ; - -exp : exp '-' exp - { write_exp_elt_opcode (BINOP_SUB); } - ; - -exp : exp LSH exp - { write_exp_elt_opcode (BINOP_LSH); } - ; - -exp : exp RSH exp - { write_exp_elt_opcode (BINOP_RSH); } - ; - -exp : exp EQUAL exp - { write_exp_elt_opcode (BINOP_EQUAL); } - ; - -exp : exp NOTEQUAL exp - { write_exp_elt_opcode (BINOP_NOTEQUAL); } - ; - -exp : exp LEQ exp - { write_exp_elt_opcode (BINOP_LEQ); } - ; - -exp : exp GEQ exp - { write_exp_elt_opcode (BINOP_GEQ); } - ; - -exp : exp '<' exp - { write_exp_elt_opcode (BINOP_LESS); } - ; - -exp : exp '>' exp - { write_exp_elt_opcode (BINOP_GTR); } - ; - -exp : exp '&' exp - { write_exp_elt_opcode (BINOP_BITWISE_AND); } - ; - -exp : exp '^' exp - { write_exp_elt_opcode (BINOP_BITWISE_XOR); } - ; - -exp : exp '|' exp - { write_exp_elt_opcode (BINOP_BITWISE_IOR); } - ; - -exp : exp ANDAND exp - { write_exp_elt_opcode (BINOP_LOGICAL_AND); } - ; - -exp : exp OROR exp - { write_exp_elt_opcode (BINOP_LOGICAL_OR); } - ; - -exp : exp '?' exp ':' exp %prec '?' - { write_exp_elt_opcode (TERNOP_COND); } - ; - -exp : exp '=' exp - { write_exp_elt_opcode (BINOP_ASSIGN); } - ; - -exp : exp ASSIGN_MODIFY exp - { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode ($2); - write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); } - ; - -exp : INT - { 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); } - ; - -exp : NAME_OR_INT - { YYSTYPE val; - parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (val.typed_val.type); - write_exp_elt_longcst ((LONGEST)val.typed_val.val); - write_exp_elt_opcode (OP_LONG); - } - ; - - -exp : FLOAT - { write_exp_elt_opcode (OP_DOUBLE); - write_exp_elt_type (builtin_type_double); - write_exp_elt_dblcst ($1); - write_exp_elt_opcode (OP_DOUBLE); } - ; - -exp : variable - ; - -exp : LAST - { write_exp_elt_opcode (OP_LAST); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_LAST); } - ; - -exp : REGNAME - { write_exp_elt_opcode (OP_REGISTER); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_REGISTER); } - ; - -exp : VARIABLE - { write_exp_elt_opcode (OP_INTERNALVAR); - write_exp_elt_intern ($1); - write_exp_elt_opcode (OP_INTERNALVAR); } - ; - -exp : SIZEOF '(' type ')' %prec UNARY - { write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_int); - write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3)); - write_exp_elt_opcode (OP_LONG); } - ; - -exp : STRING - { /* 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. - There is no such thing in C as a completely empty - string. */ - char *sp = $1.ptr; int count = $1.length; - while (count-- > 0) - { - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_char); - write_exp_elt_longcst ((LONGEST)(*sp++)); - write_exp_elt_opcode (OP_LONG); - } - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_char); - write_exp_elt_longcst ((LONGEST)'\0'); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_opcode (OP_ARRAY); - write_exp_elt_longcst ((LONGEST) 0); - write_exp_elt_longcst ((LONGEST) ($1.length)); - write_exp_elt_opcode (OP_ARRAY); } - ; - -/* C++. */ -exp : THIS - { write_exp_elt_opcode (OP_THIS); - write_exp_elt_opcode (OP_THIS); } - ; - -/* end of C++. */ - -block : BLOCKNAME - { - if ($1.sym != 0) - $$ = 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)); - } - } - ; - -block : block COLONCOLON name - { struct symbol *tem - = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) - error ("No function \"%s\" in specified context.", - copy_name ($3)); - $$ = SYMBOL_BLOCK_VALUE (tem); } - ; - -variable: block COLONCOLON name - { struct symbol *sym; - sym = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (sym == 0) - error ("No symbol \"%s\" in specified context.", - copy_name ($3)); - - write_exp_elt_opcode (OP_VAR_VALUE); - /* block_found is set by lookup_symbol. */ - write_exp_elt_block (block_found); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); } - ; - -qualified_name: typebase COLONCOLON name - { - struct type *type = $1; - if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) - error ("`%s' is not defined as an aggregate type.", - TYPE_NAME (type)); - - write_exp_elt_opcode (OP_SCOPE); - write_exp_elt_type (type); - write_exp_string ($3); - write_exp_elt_opcode (OP_SCOPE); - } - | typebase COLONCOLON '~' name - { - struct type *type = $1; - struct stoken tmp_token; - if (TYPE_CODE (type) != TYPE_CODE_STRUCT - && TYPE_CODE (type) != TYPE_CODE_UNION) - 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; - write_exp_elt_opcode (OP_SCOPE); - write_exp_elt_type (type); - write_exp_string (tmp_token); - write_exp_elt_opcode (OP_SCOPE); - } - ; - -variable: qualified_name - | COLONCOLON name - { - char *name = copy_name ($2); - struct symbol *sym; - struct minimal_symbol *msymbol; - - sym = - lookup_symbol (name, (const struct block *) NULL, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (sym) - { - write_exp_elt_opcode (OP_VAR_VALUE); - write_exp_elt_block (NULL); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); - break; - } - - msymbol = lookup_minimal_symbol (name, - (struct objfile *) NULL); - if (msymbol != NULL) - { - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_long); - write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol)); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_opcode (UNOP_MEMVAL); - if (msymbol -> type == mst_data || - msymbol -> type == mst_bss) - write_exp_elt_type (builtin_type_int); - else if (msymbol -> type == mst_text) - write_exp_elt_type (lookup_function_type (builtin_type_int)); - else - write_exp_elt_type (builtin_type_char); - write_exp_elt_opcode (UNOP_MEMVAL); - } - 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.", name); - } - ; - -variable: name_not_typename - { struct symbol *sym = $1.sym; - - if (sym) - { - 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); - } - else if ($1.is_a_field_of_this) - { - /* C++: 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 ($1.stoken); - write_exp_elt_opcode (STRUCTOP_PTR); - } - else - { - struct minimal_symbol *msymbol; - register char *arg = copy_name ($1.stoken); - - msymbol = lookup_minimal_symbol (arg, - (struct objfile *) NULL); - if (msymbol != NULL) - { - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_long); - write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol)); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_opcode (UNOP_MEMVAL); - if (msymbol -> type == mst_data || - msymbol -> type == mst_bss) - write_exp_elt_type (builtin_type_int); - else if (msymbol -> type == mst_text) - write_exp_elt_type (lookup_function_type (builtin_type_int)); - else - write_exp_elt_type (builtin_type_char); - write_exp_elt_opcode (UNOP_MEMVAL); - } - 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.", - copy_name ($1.stoken)); - } - } - ; - - -/* shift/reduce conflict: "typebase ." and the token is '('. (Shows up - twice, once where qualified_name is a possibility and once where - it is not). */ -/* shift/reduce conflict: "typebase CONST_KEYWORD ." and the token is '('. */ -/* shift/reduce conflict: "typebase VOLATILE_KEYWORD ." and the token is - '('. */ -ptype : typebase - /* "const" and "volatile" are curently ignored. A type qualifier - before the type is currently handled in the typebase rule. */ - | typebase CONST_KEYWORD - | typebase VOLATILE_KEYWORD - | typebase abs_decl - { $$ = follow_types ($1); } - | typebase CONST_KEYWORD abs_decl - { $$ = follow_types ($1); } - | typebase VOLATILE_KEYWORD abs_decl - { $$ = follow_types ($1); } - ; - -abs_decl: '*' - { push_type (tp_pointer); $$ = 0; } - | '*' abs_decl - { push_type (tp_pointer); $$ = $2; } - | '&' - { push_type (tp_reference); $$ = 0; } - | '&' abs_decl - { push_type (tp_reference); $$ = $2; } - | direct_abs_decl - ; - -direct_abs_decl: '(' abs_decl ')' - { $$ = $2; } - | direct_abs_decl array_mod - { - push_type_int ($2); - push_type (tp_array); - } - | array_mod - { - push_type_int ($1); - push_type (tp_array); - $$ = 0; - } - - /* shift/reduce conflict. "direct_abs_decl . func_mod", and the token - is '('. */ - - | direct_abs_decl func_mod - { push_type (tp_function); } - | func_mod - { push_type (tp_function); } - ; - -array_mod: '[' ']' - { $$ = -1; } - | '[' INT ']' - { $$ = $2.val; } - ; - -func_mod: '(' ')' - { $$ = 0; } - | '(' nonempty_typelist ')' - { free ((PTR)$2); $$ = 0; } - ; - -/* shift/reduce conflict: "type '(' typebase COLONCOLON '*' ')' ." and the - token is '('. */ -type : ptype - | typebase COLONCOLON '*' - { $$ = lookup_member_type (builtin_type_int, $1); } - | type '(' typebase COLONCOLON '*' ')' - { $$ = lookup_member_type ($1, $3); } - | type '(' typebase COLONCOLON '*' ')' '(' ')' - { $$ = lookup_member_type - (lookup_function_type ($1), $3); } - | type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')' - { $$ = lookup_member_type - (lookup_function_type ($1), $3); - free ((PTR)$8); } - ; - -typebase /* Implements (approximately): (type-qualifier)* type-specifier */ - : TYPENAME - { $$ = $1.type; } - | INT_KEYWORD - { $$ = builtin_type_int; } - | LONG - { $$ = builtin_type_long; } - | SHORT - { $$ = builtin_type_short; } - | LONG INT_KEYWORD - { $$ = builtin_type_long; } - | UNSIGNED LONG INT_KEYWORD - { $$ = builtin_type_unsigned_long; } - | LONG LONG - { $$ = builtin_type_long_long; } - | LONG LONG INT_KEYWORD - { $$ = builtin_type_long_long; } - | UNSIGNED LONG LONG - { $$ = builtin_type_unsigned_long_long; } - | UNSIGNED LONG LONG INT_KEYWORD - { $$ = builtin_type_unsigned_long_long; } - | SHORT INT_KEYWORD - { $$ = builtin_type_short; } - | UNSIGNED SHORT INT_KEYWORD - { $$ = builtin_type_unsigned_short; } - | STRUCT name - { $$ = lookup_struct (copy_name ($2), - expression_context_block); } - | CLASS name - { $$ = lookup_struct (copy_name ($2), - expression_context_block); } - | UNION name - { $$ = lookup_union (copy_name ($2), - expression_context_block); } - | ENUM name - { $$ = lookup_enum (copy_name ($2), - expression_context_block); } - | UNSIGNED typename - { $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); } - | UNSIGNED - { $$ = builtin_type_unsigned_int; } - | SIGNED_KEYWORD typename - { $$ = lookup_signed_typename (TYPE_NAME($2.type)); } - | SIGNED_KEYWORD - { $$ = builtin_type_int; } - | TEMPLATE name '<' type '>' - { $$ = lookup_template_type(copy_name($2), $4, - expression_context_block); - } - /* "const" and "volatile" are curently ignored. A type qualifier - after the type is handled in the ptype rule. I think these could - be too. */ - | CONST_KEYWORD typebase { $$ = $2; } - | VOLATILE_KEYWORD typebase { $$ = $2; } - ; - -typename: TYPENAME - | INT_KEYWORD - { - $$.stoken.ptr = "int"; - $$.stoken.length = 3; - $$.type = builtin_type_int; - } - | LONG - { - $$.stoken.ptr = "long"; - $$.stoken.length = 4; - $$.type = builtin_type_long; - } - | SHORT - { - $$.stoken.ptr = "short"; - $$.stoken.length = 5; - $$.type = builtin_type_short; - } - ; - -nonempty_typelist - : type - { $$ = (struct type **) malloc (sizeof (struct type *) * 2); - $$[0] = 1; /* Number of types in vector */ - $$[1] = $1; - } - | nonempty_typelist ',' type - { int len = sizeof (struct type *) * (++($1[0]) + 1); - $$ = (struct type **) realloc ((char *) $1, len); - $$[$$[0]] = $3; - } - ; - -name : NAME { $$ = $1.stoken; } - | BLOCKNAME { $$ = $1.stoken; } - | TYPENAME { $$ = $1.stoken; } - | NAME_OR_INT { $$ = $1.stoken; } - ; - -name_not_typename : NAME - | BLOCKNAME -/* These would be useful if name_not_typename was useful, but it is just - a fake for "variable", so these cause reduce/reduce conflicts because - the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable, - =exp) or just an exp. If name_not_typename was ever used in an lvalue - context where only a name could occur, this might be useful. - | NAME_OR_INT - */ - ; - -%% - -/* 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 LONGEST n = 0; - register LONGEST prevn = 0; - register int i = 0; - register int c; - register int base = input_radix; - int unsigned_p = 0; - int long_p = 0; - unsigned LONGEST high_bit; - struct type *signed_type; - struct type *unsigned_type; - - if (parsed_float) - { - /* It's a float since it contains a point or an exponent. */ - putithere->dval = atof (p); - return FLOAT; - } - - /* 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; - } - - while (len-- > 0) - { - c = *p++; - if (c >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != 'l' && c != 'u') - n *= base; - if (c >= '0' && c <= '9') - n += i = c - '0'; - else - { - if (base > 10 && c >= 'a' && c <= 'f') - n += i = c - 'a' + 10; - else if (len == 0 && c == 'l') - long_p = 1; - else if (len == 0 && c == 'u') - unsigned_p = 1; - else - return ERROR; /* Char not a digit */ - } - if (i >= base) - return ERROR; /* Invalid digit in this base */ - - /* Portably test for overflow (only works for nonzero values, so make - a second check for zero). */ - if((prevn >= n) && n != 0) - unsigned_p=1; /* Try something unsigned */ - /* If range checking enabled, portably test for unsigned overflow. */ - if(RANGE_CHECK && n!=0) - { - if((unsigned_p && (unsigned)prevn >= (unsigned)n)) - range_error("Overflow on numeric constant."); - } - prevn=n; - } - - /* If the number is too big to be an int, or it's got an l suffix - then it's a long. Work out if this has to be a long by - shifting right and and seeing if anything remains, and the - target int size is different to the target long size. - - In the expression below, we could have tested - (n >> TARGET_INT_BIT) - to see if it was zero, - but too many compilers warn about that, when ints and longs - are the same size. So we shift it twice, with fewer bits - each time, for the same result. */ - - if ( (TARGET_INT_BIT != TARGET_LONG_BIT - && ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */ - || long_p) - { - high_bit = ((unsigned LONGEST)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); - unsigned_type = builtin_type_unsigned_int; - signed_type = builtin_type_int; - } - - putithere->typed_val.val = n; - - /* If the high bit of the worked out type is set then this number - has to be unsigned. */ - - if (unsigned_p || (n & high_bit)) - { - putithere->typed_val.type = unsigned_type; - } - else - { - putithere->typed_val.type = signed_type; - } - - return INT; -} - -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}, - {"->", ARROW, BINOP_END}, - {"&&", ANDAND, BINOP_END}, - {"||", OROR, BINOP_END}, - {"::", COLONCOLON, 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); - - yylval.typed_val.val = c; - yylval.typed_val.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 INT; - - 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 '{': - 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); - } - - 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 = 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; - - /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1) - and $$digits (equivalent to $<-digits> if you could type that). - Make token type LAST, and put the number (the digits) in yylval. */ - - tryname: - if (*tokstart == '$') - { - register int negate = 0; - c = 1; - /* Double dollar means negate the number and add -1 as well. - Thus $$ alone means -1. */ - if (namelen >= 2 && tokstart[1] == '$') - { - negate = 1; - c = 2; - } - if (c == namelen) - { - /* Just dollars (one or two) */ - yylval.lval = - negate; - return LAST; - } - /* Is the rest of the token digits? */ - for (; c < namelen; c++) - if (!(tokstart[c] >= '0' && tokstart[c] <= '9')) - break; - if (c == namelen) - { - yylval.lval = atoi (tokstart + 1 + negate); - if (negate) - yylval.lval = - yylval.lval; - return LAST; - } - } - - /* Handle tokens that refer to machine registers: - $ followed by a register name. */ - - if (*tokstart == '$') { - for (c = 0; c < NUM_REGS; c++) - if (namelen - 1 == strlen (reg_names[c]) - && STREQN (tokstart + 1, reg_names[c], namelen - 1)) - { - yylval.lval = c; - return REGNAME; - } - for (c = 0; c < num_std_regs; c++) - if (namelen - 1 == strlen (std_regs[c].name) - && STREQN (tokstart + 1, std_regs[c].name, namelen - 1)) - { - yylval.lval = std_regs[c].regnum; - return REGNAME; - } - } - /* Catch specific keywords. Should be done with a data structure. */ - switch (namelen) - { - case 8: - if (STREQN (tokstart, "unsigned", 8)) - return UNSIGNED; - if (current_language->la_language == language_cplus - && STREQN (tokstart, "template", 8)) - return TEMPLATE; - if (STREQN (tokstart, "volatile", 8)) - return VOLATILE_KEYWORD; - break; - case 6: - if (STREQN (tokstart, "struct", 6)) - return STRUCT; - if (STREQN (tokstart, "signed", 6)) - return SIGNED_KEYWORD; - if (STREQN (tokstart, "sizeof", 6)) - return SIZEOF; - break; - case 5: - if (current_language->la_language == language_cplus - && STREQN (tokstart, "class", 5)) - return CLASS; - if (STREQN (tokstart, "union", 5)) - return UNION; - if (STREQN (tokstart, "short", 5)) - return SHORT; - if (STREQN (tokstart, "const", 5)) - return CONST_KEYWORD; - break; - case 4: - if (STREQN (tokstart, "enum", 4)) - 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; - } - break; - case 3: - if (STREQN (tokstart, "int", 3)) - return INT_KEYWORD; - break; - default: - break; - } - - yylval.sval.ptr = tokstart; - yylval.sval.length = namelen; - - /* Any other names starting in $ are debugger internal variables. */ - - if (*tokstart == '$') - { - yylval.ivar = lookup_internalvar (copy_name (yylval.sval) + 1); - return VARIABLE; - } - - /* 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 - currently as names of types; NAME for other symbols. - The caller is not constrained to care about the distinction. */ - { - char *tmp = copy_name (yylval.sval); - struct symbol *sym; - int is_a_field_of_this = 0; - int hextype; - - sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, - current_language->la_language == language_cplus - ? &is_a_field_of_this : (int *) NULL, - (struct symtab **) NULL); - if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) || - lookup_partial_symtab (tmp)) - { - yylval.ssym.sym = sym; - yylval.ssym.is_a_field_of_this = is_a_field_of_this; - return BLOCKNAME; - } - if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) - { - char *p; - char *namestart; - struct symbol *best_sym; - - /* Look ahead to detect nested types. This probably should be - done in the grammar, but trying seemed to introduce a lot - of shift/reduce and reduce/reduce conflicts. It's possible - that it could be done, though. Or perhaps a non-grammar, but - less ad hoc, approach would work well. */ - - /* Since we do not currently have any way of distinguishing - a nested type from a non-nested one (the stabs don't tell - us whether a type is nested), we just ignore the - containing type. */ - - p = lexptr; - best_sym = sym; - while (1) - { - /* Skip whitespace. */ - while (*p == ' ' || *p == '\t' || *p == '\n') - ++p; - if (*p == ':' && p[1] == ':') - { - /* Skip the `::'. */ - p += 2; - /* Skip whitespace. */ - while (*p == ' ' || *p == '\t' || *p == '\n') - ++p; - namestart = p; - while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9') - || (*p >= 'a' && *p <= 'z') - || (*p >= 'A' && *p <= 'Z')) - ++p; - if (p != namestart) - { - struct symbol *cur_sym; - /* As big as the whole rest of the expression, which is - at least big enough. */ - char *tmp = alloca (strlen (namestart)); - - memcpy (tmp, namestart, p - namestart); - tmp[p - namestart] = '\0'; - cur_sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (cur_sym) - { - if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF) - { - best_sym = cur_sym; - lexptr = p; - } - else - break; - } - else - break; - } - else - break; - } - else - break; - } - - yylval.tsym.type = SYMBOL_TYPE (best_sym); - return TYPENAME; - } - if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) - return TYPENAME; - - /* 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 (!sym && - ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) || - (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) - { - YYSTYPE newlval; /* Its value is ignored. */ - hextype = parse_number (tokstart, namelen, 0, &newlval); - if (hextype == INT) - { - yylval.ssym.sym = sym; - yylval.ssym.is_a_field_of_this = is_a_field_of_this; - return NAME_OR_INT; - } - } - - /* Any other kind of symbol */ - yylval.ssym.sym = sym; - yylval.ssym.is_a_field_of_this = is_a_field_of_this; - return NAME; - } -} - -void -yyerror (msg) - char *msg; -{ - error (msg ? msg : "Invalid syntax in expression."); -} diff --git a/gnu/usr.bin/gdb/gdb/c-lang.c b/gnu/usr.bin/gdb/gdb/c-lang.c deleted file mode 100644 index 9b4b3ee..0000000 --- a/gnu/usr.bin/gdb/gdb/c-lang.c +++ /dev/null @@ -1,469 +0,0 @@ -/* C language support routines for GDB, the GNU debugger. - Copyright 1992, 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. */ - -#include "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "parser-defs.h" -#include "language.h" -#include "c-lang.h" - -/* 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) - register int c; - GDB_FILE *stream; - int quoter; -{ - - c &= 0xFF; /* Avoid sign bit follies */ - - if (PRINT_LITERAL_FORM (c)) - { - if (c == '\\' || c == quoter) - { - fputs_filtered ("\\", stream); - } - fprintf_filtered (stream, "%c", c); - } - else - { - switch (c) - { - case '\n': - fputs_filtered ("\\n", stream); - break; - case '\b': - fputs_filtered ("\\b", stream); - break; - case '\t': - fputs_filtered ("\\t", stream); - break; - case '\f': - fputs_filtered ("\\f", stream); - break; - case '\r': - fputs_filtered ("\\r", stream); - break; - case '\033': - fputs_filtered ("\\e", stream); - break; - case '\007': - fputs_filtered ("\\a", stream); - break; - default: - fprintf_filtered (stream, "\\%.3o", (unsigned int) c); - break; - } - } -} - -static void -c_printchar (c, stream) - int c; - GDB_FILE *stream; -{ - fputs_filtered ("'", stream); - emit_char (c, stream, '\''); - fputs_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. */ - -static void -c_printstr (stream, string, length, force_ellipses) - GDB_FILE *stream; - char *string; - unsigned int length; - int force_ellipses; -{ - register unsigned int i; - unsigned int things_printed = 0; - int in_quotes = 0; - int need_comma = 0; - extern int inspect_it; - extern int repeat_count_threshold; - extern int print_max; - - /* 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') - length--; - - if (length == 0) - { - fputs_filtered ("\"\"", stream); - return; - } - - for (i = 0; i < length && things_printed < print_max; ++i) - { - /* Position of the character we are examining - to see whether it is repeated. */ - unsigned int rep1; - /* Number of repetitions we have detected so far. */ - unsigned int reps; - - QUIT; - - if (need_comma) - { - fputs_filtered (", ", stream); - need_comma = 0; - } - - rep1 = i + 1; - reps = 1; - while (rep1 < length && string[rep1] == string[i]) - { - ++rep1; - ++reps; - } - - if (reps > repeat_count_threshold) - { - if (in_quotes) - { - if (inspect_it) - fputs_filtered ("\\\", ", stream); - else - fputs_filtered ("\", ", stream); - in_quotes = 0; - } - c_printchar (string[i], stream); - fprintf_filtered (stream, " ", reps); - i = rep1 - 1; - things_printed += repeat_count_threshold; - need_comma = 1; - } - else - { - if (!in_quotes) - { - if (inspect_it) - fputs_filtered ("\\\"", stream); - else - fputs_filtered ("\"", stream); - in_quotes = 1; - } - emit_char (string[i], stream, '"'); - ++things_printed; - } - } - - /* Terminate the quotes if necessary. */ - if (in_quotes) - { - if (inspect_it) - fputs_filtered ("\\\"", stream); - else - fputs_filtered ("\"", stream); - } - - if (force_ellipses || i < length) - fputs_filtered ("...", stream); -} - -/* Create a fundamental C type using default reasonable for the current - target machine. - - Some object/debugging file formats (DWARF version 1, COFF, etc) do not - define fundamental types such as "int" or "double". Others (stabs or - DWARF version 2, etc) do define fundamental types. For the formats which - don't provide fundamental types, gdb can create such types using this - function. - - FIXME: Some compilers distinguish explicitly signed integral types - (signed short, signed int, signed long) from "regular" integral types - (short, int, long) in the debugging information. There is some dis- - agreement as to how useful this feature is. In particular, gcc does - not support this. Also, only some debugging formats allow the - distinction to be passed on to a debugger. For now, we always just - use "short", "int", or "long" as the type name, for both the implicit - and explicitly signed types. This also makes life easier for the - gdb test suite since we don't have to account for the differences - in output depending upon what the compiler and debugging format - support. We will probably have to re-examine the issue when gdb - starts taking it's fundamental type information directly from the - debugging information supplied by the compiler. fnf@cygnus.com */ - -static struct type * -c_create_fundamental_type (objfile, typeid) - struct objfile *objfile; - int typeid; -{ - register struct type *type = NULL; - - switch (typeid) - { - default: - /* FIXME: For now, if we are asked to produce a type not in this - language, create the equivalent of a C integer type with the - name "". When all the dust settles from the type - reconstruction work, this should probably become an error. */ - type = init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "", objfile); - warning ("internal error: no C/C++ fundamental type %d", typeid); - break; - case FT_VOID: - type = init_type (TYPE_CODE_VOID, - TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, "void", objfile); - break; - case FT_CHAR: - type = init_type (TYPE_CODE_INT, - TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, "char", objfile); - break; - case FT_SIGNED_CHAR: - type = init_type (TYPE_CODE_INT, - TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, "signed char", objfile); - break; - case FT_UNSIGNED_CHAR: - type = init_type (TYPE_CODE_INT, - TARGET_CHAR_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned char", objfile); - break; - case FT_SHORT: - type = init_type (TYPE_CODE_INT, - TARGET_SHORT_BIT / TARGET_CHAR_BIT, - 0, "short", objfile); - break; - case FT_SIGNED_SHORT: - type = init_type (TYPE_CODE_INT, - TARGET_SHORT_BIT / TARGET_CHAR_BIT, - 0, "short", objfile); /* FIXME-fnf */ - break; - case FT_UNSIGNED_SHORT: - type = init_type (TYPE_CODE_INT, - TARGET_SHORT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned short", objfile); - break; - case FT_INTEGER: - type = init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "int", objfile); - break; - case FT_SIGNED_INTEGER: - type = init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "int", objfile); /* FIXME -fnf */ - break; - case FT_UNSIGNED_INTEGER: - type = init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned int", objfile); - break; - case FT_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_BIT / TARGET_CHAR_BIT, - 0, "long", objfile); - break; - case FT_SIGNED_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_BIT / TARGET_CHAR_BIT, - 0, "long", objfile); /* FIXME -fnf */ - break; - case FT_UNSIGNED_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned long", objfile); - break; - case FT_LONG_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, - 0, "long long", objfile); - break; - case FT_SIGNED_LONG_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, - 0, "signed long long", objfile); - break; - case FT_UNSIGNED_LONG_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned long long", objfile); - break; - case FT_FLOAT: - type = init_type (TYPE_CODE_FLT, - TARGET_FLOAT_BIT / TARGET_CHAR_BIT, - 0, "float", objfile); - break; - case FT_DBL_PREC_FLOAT: - type = init_type (TYPE_CODE_FLT, - TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, - 0, "double", objfile); - break; - case FT_EXT_PREC_FLOAT: - type = init_type (TYPE_CODE_FLT, - TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, - 0, "long double", objfile); - break; - } - return (type); -} - - -/* Table mapping opcodes into strings for printing operators - and precedences of the operators. */ - -static const struct op_print c_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}, - {"+", 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}, - {"@", BINOP_REPEAT, PREC_REPEAT, 0}, - {"-", UNOP_NEG, PREC_PREFIX, 0}, - {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0}, - {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0}, - {"*", UNOP_IND, PREC_PREFIX, 0}, - {"&", UNOP_ADDR, PREC_PREFIX, 0}, - {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0}, - {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0}, - {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}, - /* C++ */ - {"::", BINOP_SCOPE, PREC_PREFIX, 0}, - {NULL, 0, 0, 0} -}; - -struct type ** const (c_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, - 0 -}; - -const struct language_defn c_language_defn = { - "c", /* Language name */ - language_c, - c_builtin_types, - range_check_off, - type_check_off, - c_parse, - c_error, - c_printchar, /* Print a character constant */ - c_printstr, /* Function to print string constant */ - 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 */ - c_value_print, /* Print a top-level value */ - &builtin_type_double, /* longest floating point type */ /*FIXME*/ - {"", "", "", ""}, /* Binary format info */ - {"0%lo", "0", "o", ""}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0x%lx", "0x", "x", ""}, /* Hex format info */ - c_op_print_tab, /* expression operators for printing */ - LANG_MAGIC -}; - -const struct language_defn cplus_language_defn = { - "c++", /* Language name */ - language_cplus, - c_builtin_types, - range_check_off, - type_check_off, - c_parse, - c_error, - c_printchar, /* Print a character constant */ - c_printstr, /* Function to print string constant */ - 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 */ - c_value_print, /* Print a top-level value */ - &builtin_type_double, /* longest floating point type */ /*FIXME*/ - {"", "", "", ""}, /* Binary format info */ - {"0%lo", "0", "o", ""}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0x%lx", "0x", "x", ""}, /* Hex format info */ - c_op_print_tab, /* expression operators for printing */ - LANG_MAGIC -}; - -const struct language_defn asm_language_defn = { - "asm", /* Language name */ - language_asm, - c_builtin_types, - range_check_off, - type_check_off, - c_parse, - c_error, - c_printchar, /* Print a character constant */ - c_printstr, /* Function to print string constant */ - 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 */ - c_value_print, /* Print a top-level value */ - &builtin_type_double, /* longest floating point type */ /*FIXME*/ - {"", "", "", ""}, /* Binary format info */ - {"0%lo", "0", "o", ""}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0x%lx", "0x", "x", ""}, /* Hex format info */ - c_op_print_tab, /* expression operators for printing */ - LANG_MAGIC -}; - -void -_initialize_c_language () -{ - add_language (&c_language_defn); - add_language (&cplus_language_defn); - add_language (&asm_language_defn); -} diff --git a/gnu/usr.bin/gdb/gdb/c-lang.h b/gnu/usr.bin/gdb/gdb/c-lang.h deleted file mode 100644 index 0ea013d..0000000 --- a/gnu/usr.bin/gdb/gdb/c-lang.h +++ /dev/null @@ -1,38 +0,0 @@ -/* C language support definitions for GDB, the GNU debugger. - Copyright 1992 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. */ - -#ifdef __STDC__ /* Forward decls for prototypes */ -struct value; -#endif - -extern int -c_parse PARAMS ((void)); /* Defined in c-exp.y */ - -extern void -c_error PARAMS ((char *)); /* Defined in c-exp.y */ - -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, - int, enum val_prettyprint)); - -extern int -c_value_print PARAMS ((struct value *, GDB_FILE *, int, enum val_prettyprint)); diff --git a/gnu/usr.bin/gdb/gdb/c-typeprint.c b/gnu/usr.bin/gdb/gdb/c-typeprint.c deleted file mode 100644 index 8d915df..0000000 --- a/gnu/usr.bin/gdb/gdb/c-typeprint.c +++ /dev/null @@ -1,795 +0,0 @@ -/* Support for printing C and C++ types for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991 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 "defs.h" -#include "obstack.h" -#include "bfd.h" /* Binary File Description */ -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "value.h" -#include "gdbcore.h" -#include "target.h" -#include "command.h" -#include "gdbcmd.h" -#include "language.h" -#include "demangle.h" -#include "c-lang.h" -#include "typeprint.h" - -#include -#include - -static void -c_type_print_args PARAMS ((struct type *, GDB_FILE *)); - -static void -c_type_print_varspec_suffix PARAMS ((struct type *, GDB_FILE *, int, int, int)); - -static void -cp_type_print_derivation_info PARAMS ((GDB_FILE *, struct type *)); - -void -c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int)); - -void -c_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int)); - - -/* Print a description of a type in the format of a - typedef for the current language. - NEW is the new name for a type TYPE. */ - -void -c_typedef_print (type, new, stream) - struct type *type; - struct symbol *new; - GDB_FILE *stream; -{ - switch (current_language->la_language) - { -#ifdef _LANG_c - case language_c: - case language_cplus: - fprintf_filtered(stream, "typedef "); - type_print(type,"",stream,0); - if(TYPE_NAME ((SYMBOL_TYPE (new))) == 0 - || !STREQ (TYPE_NAME ((SYMBOL_TYPE (new))), SYMBOL_NAME (new))) - fprintf_filtered(stream, " %s", SYMBOL_SOURCE_NAME(new)); - break; -#endif -#ifdef _LANG_m2 - case language_m2: - fprintf_filtered(stream, "TYPE "); - if(!TYPE_NAME(SYMBOL_TYPE(new)) || - !STREQ (TYPE_NAME(SYMBOL_TYPE(new)), SYMBOL_NAME(new))) - fprintf_filtered(stream, "%s = ", SYMBOL_SOURCE_NAME(new)); - else - fprintf_filtered(stream, " = "); - type_print(type,"",stream,0); - break; -#endif -#ifdef _LANG_chill - case language_chill: - error ("Missing Chill support in function c_typedef_print."); /*FIXME*/ -#endif - default: - error("Language not supported."); - } - fprintf_filtered(stream, ";\n"); -} - - -/* LEVEL is the depth to indent lines by. */ - -void -c_print_type (type, varstring, stream, show, level) - struct type *type; - char *varstring; - GDB_FILE *stream; - int show; - int level; -{ - register enum type_code code; - int demangled_args; - - c_type_print_base (type, stream, show, level); - code = TYPE_CODE (type); - if ((varstring != NULL && *varstring != '\0') - || - /* Need a space if going to print stars or brackets; - but not if we will print just a type name. */ - ((show > 0 || TYPE_NAME (type) == 0) - && - (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC - || code == TYPE_CODE_METHOD - || code == TYPE_CODE_ARRAY - || code == TYPE_CODE_MEMBER - || code == TYPE_CODE_REF))) - 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 = varstring[strlen(varstring) - 1] == ')'; - c_type_print_varspec_suffix (type, stream, show, 0, demangled_args); - -} - -/* 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; - } - } - fprintf_filtered (stream, ")"); -} - -/* If TYPE is a derived type, then print out derivation information. - Print only the actual base classes of this type, not the base classes - of the base classes. I.E. for the derivation hierarchy: - - class A { int a; }; - class B : public A {int b; }; - class C : public B {int c; }; - - Print the type of class C as: - - class C : public B { - int c; - } - - Not as the following (like gdb used to), which is not legal C++ syntax for - derived types and may be confused with the multiple inheritance form: - - class C : public B : public A { - int c; - } - - In general, gdb should try to print the types as closely as possible to - the form that they appear in the source code. */ - -static void -cp_type_print_derivation_info (stream, type) - GDB_FILE *stream; - struct type *type; -{ - char *name; - int i; - - for (i = 0; i < TYPE_N_BASECLASSES (type); i++) - { - fputs_filtered (i == 0 ? ": " : ", ", stream); - fprintf_filtered (stream, "%s%s ", - BASETYPE_VIA_PUBLIC (type, i) ? "public" : "private", - BASETYPE_VIA_VIRTUAL(type, i) ? " virtual" : ""); - name = type_name_no_tag (TYPE_BASECLASS (type, i)); - fprintf_filtered (stream, "%s", name ? name : "(null)"); - } - if (i > 0) - { - fputs_filtered (" ", stream); - } -} - -/* Print any asterisks or open-parentheses needed before the - variable name (to describe its type). - - On outermost call, pass 0 for PASSED_A_PTR. - On outermost call, SHOW > 0 means should ignore - any typename for TYPE and show its details. - SHOW is always zero on recursive calls. */ - -void -c_type_print_varspec_prefix (type, stream, show, passed_a_ptr) - struct type *type; - GDB_FILE *stream; - int show; - int passed_a_ptr; -{ - char *name; - if (type == 0) - return; - - if (TYPE_NAME (type) && show <= 0) - return; - - QUIT; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_PTR: - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); - fprintf_filtered (stream, "*"); - break; - - case TYPE_CODE_MEMBER: - if (passed_a_ptr) - fprintf_filtered (stream, "("); - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); - fprintf_filtered (stream, " "); - name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); - if (name) - fputs_filtered (name, stream); - else - c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr); - fprintf_filtered (stream, "::"); - break; - - case TYPE_CODE_METHOD: - if (passed_a_ptr) - fprintf_unfiltered (stream, "("); - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); - if (passed_a_ptr) - { - fprintf_filtered (stream, " "); - c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr); - fprintf_filtered (stream, "::"); - } - break; - - case TYPE_CODE_REF: - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); - fprintf_filtered (stream, "&"); - break; - - case TYPE_CODE_FUNC: - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); - if (passed_a_ptr) - fprintf_filtered (stream, "("); - break; - - case TYPE_CODE_ARRAY: - c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); - if (passed_a_ptr) - fprintf_filtered (stream, "("); - break; - - case TYPE_CODE_UNDEF: - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - case TYPE_CODE_ENUM: - case TYPE_CODE_INT: - case TYPE_CODE_FLT: - case TYPE_CODE_VOID: - case TYPE_CODE_ERROR: - case TYPE_CODE_CHAR: - case TYPE_CODE_BOOL: - case TYPE_CODE_SET: - case TYPE_CODE_RANGE: - case TYPE_CODE_STRING: - case TYPE_CODE_BITSTRING: - /* These types need no prefix. They are listed here so that - gcc -Wall will reveal any types that haven't been handled. */ - break; - } -} - -static void -c_type_print_args (type, stream) - struct type *type; - GDB_FILE *stream; -{ - int i; - struct type **args; - - fprintf_filtered (stream, "("); - args = TYPE_ARG_TYPES (type); - if (args != NULL) - { - if (args[1] == NULL) - { - fprintf_filtered (stream, "..."); - } - else - { - for (i = 1; - args[i] != NULL && args[i]->code != TYPE_CODE_VOID; - i++) - { - c_print_type (args[i], "", stream, -1, 0); - if (args[i+1] == NULL) - { - fprintf_filtered (stream, "..."); - } - else if (args[i+1]->code != TYPE_CODE_VOID) - { - fprintf_filtered (stream, ","); - wrap_here (" "); - } - } - } - } - fprintf_filtered (stream, ")"); -} - -/* Print any array sizes, function arguments or close parentheses - needed after the variable name (to describe its type). - Args work like c_type_print_varspec_prefix. */ - -static void -c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args) - struct type *type; - GDB_FILE *stream; - int show; - int passed_a_ptr; - int demangled_args; -{ - if (type == 0) - return; - - if (TYPE_NAME (type) && show <= 0) - return; - - QUIT; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: - if (passed_a_ptr) - fprintf_filtered (stream, ")"); - - fprintf_filtered (stream, "["); - if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) - fprintf_filtered (stream, "%d", - (TYPE_LENGTH (type) - / TYPE_LENGTH (TYPE_TARGET_TYPE (type)))); - fprintf_filtered (stream, "]"); - - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); - break; - - case TYPE_CODE_MEMBER: - if (passed_a_ptr) - fprintf_filtered (stream, ")"); - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); - break; - - case TYPE_CODE_METHOD: - if (passed_a_ptr) - fprintf_filtered (stream, ")"); - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); - if (passed_a_ptr) - { - c_type_print_args (type, stream); - } - break; - - case TYPE_CODE_PTR: - case TYPE_CODE_REF: - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0); - break; - - case TYPE_CODE_FUNC: - if (passed_a_ptr) - fprintf_filtered (stream, ")"); - if (!demangled_args) - fprintf_filtered (stream, "()"); - c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, - passed_a_ptr, 0); - break; - - case TYPE_CODE_UNDEF: - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - case TYPE_CODE_ENUM: - case TYPE_CODE_INT: - case TYPE_CODE_FLT: - case TYPE_CODE_VOID: - case TYPE_CODE_ERROR: - case TYPE_CODE_CHAR: - case TYPE_CODE_BOOL: - case TYPE_CODE_SET: - case TYPE_CODE_RANGE: - case TYPE_CODE_STRING: - case TYPE_CODE_BITSTRING: - /* These types do not need a suffix. They are listed so that - gcc -Wall will report types that may not have been considered. */ - break; - } -} - -/* 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 -c_type_print_base (type, stream, show, level) - struct type *type; - GDB_FILE *stream; - int show; - int level; -{ - register int i; - register int len; - register int lastval; - char *mangled_name; - char *demangled_name; - enum {s_none, s_public, s_private, s_protected} section_type; - QUIT; - - wrap_here (" "); - if (type == NULL) - { - fputs_filtered ("", 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 we have "typedef struct foo {. . .} bar;" do we want to print it - as "struct foo" or as "bar"? Pick the latter, because C++ folk tend - to expect things like "class5 *foo" rather than "struct class5 *foo". */ - - if (show <= 0 - && TYPE_NAME (type) != NULL) - { - fputs_filtered (TYPE_NAME (type), stream); - return; - } - - check_stub_type (type); - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: - case TYPE_CODE_PTR: - case TYPE_CODE_MEMBER: - case TYPE_CODE_REF: - case TYPE_CODE_FUNC: - case TYPE_CODE_METHOD: - c_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); - break; - - case TYPE_CODE_STRUCT: - if (HAVE_CPLUS_STRUCT (type)) - { - fprintf_filtered (stream, "class "); - } - else - { - fprintf_filtered (stream, "struct "); - } - goto struct_union; - - case TYPE_CODE_UNION: - fprintf_filtered (stream, "union "); - - struct_union: - 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) - { - cp_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, "\n"); - else - fprintfi_filtered (level + 4, stream, "\n"); - } - - /* Start off with no specific section type, so we can print - one for the first field we find, and use that section type - thereafter until we find another type. */ - - section_type = s_none; - - /* 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 ((TYPE_FIELD_NAME (type, i))[5] == CPLUS_MARKER && - !strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5)) - continue; - - /* If this is a C++ class we can print the various C++ section - labels. */ - - if (HAVE_CPLUS_STRUCT (type)) - { - if (TYPE_FIELD_PROTECTED (type, i)) - { - if (section_type != s_protected) - { - section_type = s_protected; - fprintfi_filtered (level + 2, stream, - "protected:\n"); - } - } - else if (TYPE_FIELD_PRIVATE (type, i)) - { - if (section_type != s_private) - { - section_type = s_private; - fprintfi_filtered (level + 2, stream, "private:\n"); - } - } - else - { - if (section_type != s_public) - { - section_type = s_public; - fprintfi_filtered (level + 2, stream, "public:\n"); - } - } - } - - print_spaces_filtered (level + 4, stream); - if (TYPE_FIELD_STATIC (type, i)) - { - fprintf_filtered (stream, "static "); - } - c_print_type (TYPE_FIELD_TYPE (type, i), - TYPE_FIELD_NAME (type, i), - stream, show - 1, level + 4); - if (!TYPE_FIELD_STATIC (type, i) - && TYPE_FIELD_PACKED (type, i)) - { - /* It is a bitfield. This code does not attempt - to look at the bitpos and reconstruct filler, - unnamed fields. This would lead to misleading - results if the compiler does not put out fields - for such things (I don't know what it does). */ - fprintf_filtered (stream, " : %d", - TYPE_FIELD_BITSIZE (type, i)); - } - fprintf_filtered (stream, ";\n"); - } - - /* If there are both fields and methods, put a space between. */ - len = TYPE_NFN_FIELDS (type); - if (len && section_type != s_none) - fprintf_filtered (stream, "\n"); - - /* C++: print out the methods */ - - for (i = 0; i < len; i++) - { - struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); - int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); - char *method_name = TYPE_FN_FIELDLIST_NAME (type, i); - char *name = type_name_no_tag (type); - int is_constructor = name && STREQ(method_name, name); - for (j = 0; j < len2; j++) - { - QUIT; - if (TYPE_FN_FIELD_PROTECTED (f, j)) - { - if (section_type != s_protected) - { - section_type = s_protected; - fprintfi_filtered (level + 2, stream, - "protected:\n"); - } - } - else if (TYPE_FN_FIELD_PRIVATE (f, j)) - { - if (section_type != s_private) - { - section_type = s_private; - fprintfi_filtered (level + 2, stream, "private:\n"); - } - } - else - { - if (section_type != s_public) - { - section_type = s_public; - fprintfi_filtered (level + 2, stream, "public:\n"); - } - } - - print_spaces_filtered (level + 4, stream); - if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) - fprintf_filtered (stream, "virtual "); - else if (TYPE_FN_FIELD_STATIC_P (f, j)) - fprintf_filtered (stream, "static "); - if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0) - { - /* Keep GDB from crashing here. */ - fprintf_unfiltered (stream, " %s;\n", - TYPE_FN_FIELD_PHYSNAME (f, j)); - break; - } - else if (!is_constructor) - { - type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), - "", stream, 0); - fputs_filtered (" ", stream); - } - if (TYPE_FN_FIELD_STUB (f, j)) - { - /* 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, "", - mangled_name); - else - { - 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); - } - free (mangled_name); - } - else if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_' - && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER) - 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); - - fprintf_filtered (stream, ";\n"); - } - } - - fprintfi_filtered (level, stream, "}"); - } - break; - - case TYPE_CODE_ENUM: - fprintf_filtered (stream, "enum "); - 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) - { - fprintf_filtered (stream, "{"); - len = TYPE_NFIELDS (type); - lastval = 0; - for (i = 0; i < len; i++) - { - QUIT; - if (i) fprintf_filtered (stream, ", "); - wrap_here (" "); - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - if (lastval != TYPE_FIELD_BITPOS (type, i)) - { - fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i)); - lastval = TYPE_FIELD_BITPOS (type, i); - } - lastval++; - } - fprintf_filtered (stream, "}"); - } - break; - - case TYPE_CODE_VOID: - fprintf_filtered (stream, "void"); - break; - - case TYPE_CODE_UNDEF: - fprintf_filtered (stream, "struct "); - break; - - case TYPE_CODE_ERROR: - fprintf_filtered (stream, ""); - break; - - case TYPE_CODE_RANGE: - /* This should not occur */ - fprintf_filtered (stream, ""); - break; - - default: - /* Handle types not explicitly handled by the other cases, - such as fundamental types. For these, just print whatever - the type name is, as recorded in the type itself. If there - is no type name, then complain. */ - if (TYPE_NAME (type) != NULL) - { - fputs_filtered (TYPE_NAME (type), stream); - } - else - { - /* At least for dump_symtab, it is important that this not be - an error (). */ - fprintf_filtered (stream, "", - TYPE_CODE (type)); - } - break; - } -} - diff --git a/gnu/usr.bin/gdb/gdb/c-valprint.c b/gnu/usr.bin/gdb/gdb/c-valprint.c deleted file mode 100644 index 3ba7e84..0000000 --- a/gnu/usr.bin/gdb/gdb/c-valprint.c +++ /dev/null @@ -1,513 +0,0 @@ -/* Support for printing C values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "value.h" -#include "demangle.h" -#include "valprint.h" -#include "language.h" - -/* BEGIN-FIXME */ - -extern int vtblprint; /* Controls printing of vtbl's */ - -extern void -cp_print_class_member PARAMS ((char *, struct type *, GDB_FILE *, char *)); - -extern void -cp_print_class_method PARAMS ((char *, struct type *, GDB_FILE *)); - -extern void -cp_print_value_fields PARAMS ((struct type *, char *, GDB_FILE *, int, int, - enum val_prettyprint, struct type **)); - -extern int -cp_is_vtbl_ptr_type PARAMS ((struct type *)); - -extern int -cp_is_vtbl_member PARAMS ((struct type *)); - -/* END-FIXME */ - - -/* BEGIN-FIXME: Hooks into c-typeprint.c */ - -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 *)); -/* END-FIXME */ - - -extern struct obstack dont_print_obstack; - - -/* 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 -c_val_print (type, valaddr, 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 */ - unsigned len; - struct type *elttype; - unsigned eltlen; - LONGEST val; - CORE_ADDR addr; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: - if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) - { - elttype = TYPE_TARGET_TYPE (type); - eltlen = TYPE_LENGTH (elttype); - len = TYPE_LENGTH (type) / eltlen; - if (prettyprint_arrays) - { - print_spaces_filtered (2 + 2 * recurse, stream); - } - /* For an array of chars, print with string syntax. */ - if (eltlen == 1 && - ((TYPE_CODE (elttype) == TYPE_CODE_INT) - || ((current_language->la_language == language_m2) - && (TYPE_CODE (elttype) == TYPE_CODE_CHAR))) - && (format == 0 || format == 's')) - { - /* If requested, look for the first null char and only print - elements up to it. */ - if (stop_print_at_null) - { - int temp_len; - - /* Look for a NULL char. */ - for (temp_len = 0; - valaddr[temp_len] - && temp_len < len && temp_len < print_max; - temp_len++); - len = temp_len; - } - - LA_PRINT_STRING (stream, valaddr, len, 0); - i = len; - } - else - { - fprintf_filtered (stream, "{"); - /* If this is a virtual function table, print the 0th - entry specially, and the rest of the members normally. */ - if (cp_is_vtbl_ptr_type (elttype)) - { - i = 1; - fprintf_filtered (stream, "%d vtable entries", len - 1); - } - else - { - i = 0; - } - val_print_array_elements (type, valaddr, address, stream, - format, deref_ref, recurse, pretty, i); - fprintf_filtered (stream, "}"); - } - break; - } - /* Array of unspecified length: treat like pointer to first elt. */ - addr = address; - goto print_unpacked_pointer; - - case TYPE_CODE_PTR: - if (format && format != 's') - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } - 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; - } - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD) - { - cp_print_class_method (valaddr, type, stream); - } - else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER) - { - cp_print_class_member (valaddr, - TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)), - stream, "&"); - } - else - { - addr = unpack_pointer (type, valaddr); - print_unpacked_pointer: - elttype = TYPE_TARGET_TYPE (type); - - if (TYPE_CODE (elttype) == 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') - { - print_address_numeric (addr, 1, stream); - } - - /* For a pointer to char or unsigned char, also print the string - pointed to, unless pointer is null. */ - if (TYPE_LENGTH (elttype) == 1 - && TYPE_CODE (elttype) == TYPE_CODE_INT - && (format == 0 || format == 's') - && addr != 0) - { - i = val_print_string (addr, 0, stream); - } - else if (cp_is_vtbl_member(type)) - { - /* print vtbl's nicely */ - CORE_ADDR vt_address = unpack_pointer (type, valaddr); - - struct minimal_symbol *msymbol = - lookup_minimal_symbol_by_pc (vt_address); - if ((msymbol != NULL) && - (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) - { - fputs_filtered (" <", stream); - fputs_filtered (SYMBOL_SOURCE_NAME (msymbol), stream); - fputs_filtered (">", stream); - } - if (vt_address && vtblprint) - { - value_ptr vt_val; - struct symbol *wsym = (struct symbol *)NULL; - struct type *wtype; - struct symtab *s; - struct block *block = (struct block *)NULL; - int is_this_fld; - - if (msymbol != NULL) - wsym = lookup_symbol (SYMBOL_NAME(msymbol), block, - VAR_NAMESPACE, &is_this_fld, &s); - - if (wsym) - { - wtype = SYMBOL_TYPE(wsym); - } - else - { - wtype = TYPE_TARGET_TYPE(type); - } - vt_val = value_at (wtype, vt_address); - val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val), - VALUE_ADDRESS (vt_val), stream, format, - deref_ref, recurse + 1, pretty); - if (pretty) - { - fprintf_filtered (stream, "\n"); - print_spaces_filtered (2 + 2 * recurse, stream); - } - } - } - - /* Return number of characters printed, including the terminating - '\0' if we reached the end. val_print_string takes care including - the terminating '\0' if necessary. */ - return i; - } - break; - - case TYPE_CODE_MEMBER: - error ("not implemented: member type in c_val_print"); - break; - - case TYPE_CODE_REF: - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER) - { - cp_print_class_member (valaddr, - TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)), - stream, ""); - break; - } - if (addressprint) - { - fprintf_filtered (stream, "@"); - print_address_numeric - (extract_address (valaddr, - TARGET_PTR_BIT / HOST_CHAR_BIT), 1, stream); - if (deref_ref) - fputs_filtered (": ", stream); - } - /* De-reference the reference. */ - if (deref_ref) - { - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF) - { - value_ptr deref_val = - value_at - (TYPE_TARGET_TYPE (type), - unpack_pointer (lookup_pointer_type (builtin_type_void), - valaddr)); - val_print (VALUE_TYPE (deref_val), - VALUE_CONTENTS (deref_val), - VALUE_ADDRESS (deref_val), stream, format, - deref_ref, recurse + 1, pretty); - } - else - fputs_filtered ("???", stream); - } - break; - - case TYPE_CODE_UNION: - if (recurse && !unionprint) - { - fprintf_filtered (stream, "{...}"); - break; - } - /* Fall through. */ - case TYPE_CODE_STRUCT: - if (vtblprint && cp_is_vtbl_ptr_type(type)) - { - /* 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); - break; - } - cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, - 0); - break; - - case TYPE_CODE_ENUM: - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } - len = TYPE_NFIELDS (type); - val = unpack_long (type, valaddr); - for (i = 0; i < len; i++) - { - QUIT; - if (val == TYPE_FIELD_BITPOS (type, i)) - { - break; - } - } - if (i < len) - { - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } - else - { - print_longest (stream, 'd', 0, val); - } - break; - - case TYPE_CODE_FUNC: - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } - /* FIXME, we should consider, at least for ANSI C language, eliminating - the distinction made between FUNCs and POINTERs to FUNCs. */ - fprintf_filtered (stream, "{"); - type_print (type, "", stream, -1); - fprintf_filtered (stream, "} "); - /* Try to print what function it points to, and its address. */ - print_address_demangle (address, stream, demangle); - break; - - case TYPE_CODE_BOOL: - /* Do something at least vaguely reasonable, for example if the - language is set wrong. */ - - case TYPE_CODE_RANGE: - /* FIXME: create_range_type does not set the unsigned bit in a - range type (I think it probably should copy it from the target - type), so we won't print values which are too large to - fit in a signed integer correctly. */ - /* FIXME: Doesn't handle ranges of enums correctly. (Can't just - print with the target type, though, because the size of our type - and the target type might differ). */ - /* FALLTHROUGH */ - - case TYPE_CODE_INT: - format = format ? format : output_format; - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - } - else - { - val_print_type_code_int (type, valaddr, 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 - equivalent as well. */ - if (TYPE_LENGTH (type) == 1) - { - fputs_filtered (" ", stream); - LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr), - stream); - } - } - break; - - case TYPE_CODE_CHAR: - format = format ? format : output_format; - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - } - else - { - fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%u" : "%d", - unpack_long (type, valaddr)); - fputs_filtered (" ", stream); - LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr), stream); - } - break; - - case TYPE_CODE_FLT: - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - } - else - { - print_floating (valaddr, type, stream); - } - break; - - case TYPE_CODE_VOID: - fprintf_filtered (stream, "void"); - break; - - case TYPE_CODE_ERROR: - fprintf_filtered (stream, ""); - break; - - case TYPE_CODE_UNDEF: - /* This happens (without TYPE_FLAG_STUB set) on systems which don't use - dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" - and no complete type for struct foo in that file. */ - fprintf_filtered (stream, ""); - break; - - default: - error ("Invalid C/C++ type code %d in symbol table.", TYPE_CODE (type)); - } - gdb_flush (stream); - return (0); -} - -int -c_value_print (val, stream, format, pretty) - value_ptr val; - GDB_FILE *stream; - int format; - enum val_prettyprint pretty; -{ - /* A "repeated" value really contains several values in a row. - They are made by the @ operator. - Print such values as if they were arrays. */ - - if (VALUE_REPEATED (val)) - { - register unsigned int n = VALUE_REPETITIONS (val); - register unsigned int typelen = TYPE_LENGTH (VALUE_TYPE (val)); - fprintf_filtered (stream, "{"); - /* Print arrays of characters using string syntax. */ - if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT - && format == 0) - LA_PRINT_STRING (stream, VALUE_CONTENTS (val), n, 0); - else - { - value_print_array_elements (val, stream, format, pretty); - } - fprintf_filtered (stream, "}"); - return (n * typelen); - } - else - { - struct type *type = VALUE_TYPE (val); - - /* If it is a pointer, indicate what it points to. - - Print type also if it is a reference. - - C++: if it is a member pointer, we will take care - of that when we print it. */ - if (TYPE_CODE (type) == TYPE_CODE_PTR || - TYPE_CODE (type) == TYPE_CODE_REF) - { - /* Hack: remove (char *) for char strings. Their - type is indicated by the quoted string anyway. */ - if (TYPE_CODE (type) == TYPE_CODE_PTR && - TYPE_LENGTH (TYPE_TARGET_TYPE (type)) == sizeof(char) && - TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_INT && - !TYPE_UNSIGNED (TYPE_TARGET_TYPE (type))) - { - /* Print nothing */ - } - else - { - 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)); - } -} diff --git a/gnu/usr.bin/gdb/gdb/call-cmds.h b/gnu/usr.bin/gdb/gdb/call-cmds.h deleted file mode 100644 index 9030d84..0000000 --- a/gnu/usr.bin/gdb/gdb/call-cmds.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Prototypes for GDB commands that are called internally by other functions. - Copyright 1992 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -extern void -initialize_all_files PARAMS ((void)); - -extern void -exec_file_command PARAMS ((char *, int)); - -extern void -core_file_command PARAMS ((char *, int)); - -extern void -break_command PARAMS ((char *, int)); diff --git a/gnu/usr.bin/gdb/gdb/ch-exp.y b/gnu/usr.bin/gdb/gdb/ch-exp.y deleted file mode 100644 index b6370f3..0000000 --- a/gnu/usr.bin/gdb/gdb/ch-exp.y +++ /dev/null @@ -1,1997 +0,0 @@ -/* YACC grammar for Chill expressions, for GDB. - Copyright 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. */ - -/* Parse a Chill 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. - - 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 ( and for example) just became - too messy, particularly when such includes can be inserted at random - times by the parser generator. - - Also note that the language accepted by this parser is more liberal - than the one accepted by an actual Chill compiler. For example, the - language rule that a simple name string can not be one of the reserved - simple name strings is not enforced (e.g "case" is not treated as a - reserved name). Another example is that Chill is a strongly typed - language, and certain expressions that violate the type constraints - may still be evaluated if gdb can do so in a meaningful manner, while - such expressions would be rejected by the compiler. The reason for - this more liberal behavior is the philosophy that the debugger - is intended to be a tool that is used by the programmer when things - go wrong, and as such, it should provide as few artificial barriers - to it's use as possible. If it can do something meaningful, even - something that violates language contraints that are enforced by the - compiler, it should do so without complaint. - - */ - -%{ - -#include "defs.h" -#include -#include "expression.h" -#include "language.h" -#include "value.h" -#include "parser-defs.h" -#include "ch-lang.h" - -/* 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 chill_maxdepth -#define yyparse chill_parse -#define yylex chill_lex -#define yyerror chill_error -#define yylval chill_lval -#define yychar chill_char -#define yydebug chill_debug -#define yypact chill_pact -#define yyr1 chill_r1 -#define yyr2 chill_r2 -#define yydef chill_def -#define yychk chill_chk -#define yypgo chill_pgo -#define yyact chill_act -#define yyexca chill_exca -#define yyerrflag chill_errflag -#define yynerrs chill_nerrs -#define yyps chill_ps -#define yypv chill_pv -#define yys chill_s -#define yy_yys chill_yys -#define yystate chill_state -#define yytmp chill_tmp -#define yyv chill_v -#define yy_yyv chill_yyv -#define yyval chill_val -#define yylloc chill_lloc -#define yyreds chill_reds /* With YYDEBUG defined */ -#define yytoks chill_toks /* With YYDEBUG defined */ - -#ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ -#endif - -int -yyparse PARAMS ((void)); - -static int -yylex PARAMS ((void)); - -void -yyerror PARAMS ((char *)); - -%} - -/* 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; - unsigned LONGEST ulval; - struct { - LONGEST val; - struct type *type; - } typed_val; - double dval; - struct symbol *sym; - struct type *tval; - struct stoken sval; - struct ttype tsym; - struct symtoken ssym; - int voidval; - struct block *bval; - enum exp_opcode opcode; - struct internalvar *ivar; - - struct type **tvec; - int *ivec; - } - -%token FIXME_01 -%token FIXME_02 -%token FIXME_03 -%token FIXME_04 -%token FIXME_05 -%token FIXME_06 -%token FIXME_07 -%token FIXME_08 -%token FIXME_09 -%token FIXME_10 -%token FIXME_11 -%token FIXME_12 -%token FIXME_13 -%token FIXME_14 -%token FIXME_15 -%token FIXME_16 -%token FIXME_17 -%token FIXME_18 -%token FIXME_19 -%token FIXME_20 -%token FIXME_21 -%token FIXME_22 -%token FIXME_24 -%token FIXME_25 -%token FIXME_26 -%token FIXME_27 -%token FIXME_28 -%token FIXME_29 -%token FIXME_30 - -%token INTEGER_LITERAL -%token BOOLEAN_LITERAL -%token CHARACTER_LITERAL -%token FLOAT_LITERAL -%token GENERAL_PROCEDURE_NAME -%token LOCATION_NAME -%token SET_LITERAL -%token EMPTINESS_LITERAL -%token CHARACTER_STRING_LITERAL -%token BIT_STRING_LITERAL -%token TYPENAME -%token FIELD_NAME - -%token '.' -%token ';' -%token ':' -%token CASE -%token OF -%token ESAC -%token LOGIOR -%token ORIF -%token LOGXOR -%token LOGAND -%token ANDIF -%token '=' -%token NOTEQUAL -%token '>' -%token GTR -%token '<' -%token LEQ -%token IN -%token '+' -%token '-' -%token '*' -%token '/' -%token SLASH_SLASH -%token MOD -%token REM -%token NOT -%token POINTER -%token RECEIVE -%token '[' -%token ']' -%token '(' -%token ')' -%token UP -%token IF -%token THEN -%token ELSE -%token FI -%token ELSIF -%token ILLEGAL_TOKEN -%token NUM -%token PRED -%token SUCC -%token ABS -%token CARD -%token MAX_TOKEN -%token MIN_TOKEN -%token SIZE -%token UPPER -%token LOWER -%token LENGTH - -/* Tokens which are not Chill tokens used in expressions, but rather GDB - specific things that we recognize in the same context as Chill tokens - (register names for example). */ - -%token GDB_REGNAME /* Machine register name */ -%token GDB_LAST /* Value history */ -%token GDB_VARIABLE /* Convenience variable */ -%token GDB_ASSIGNMENT /* Assign value to somewhere */ - -%type location -%type access_name -%type primitive_value -%type location_contents -%type value_name -%type literal -%type tuple -%type value_string_element -%type value_string_slice -%type value_array_element -%type value_array_slice -%type value_structure_field -%type expression_conversion -%type value_procedure_call -%type value_built_in_routine_call -%type chill_value_built_in_routine_call -%type start_expression -%type zero_adic_operator -%type parenthesised_expression -%type value -%type undefined_value -%type expression -%type conditional_expression -%type then_alternative -%type else_alternative -%type sub_expression -%type value_case_alternative -%type operand_0 -%type operand_1 -%type operand_2 -%type operand_3 -%type operand_4 -%type operand_5 -%type operand_6 -%type synonym_name -%type value_enumeration_name -%type value_do_with_name -%type value_receive_name -%type string_primitive_value -%type start_element -%type left_element -%type right_element -%type slice_size -%type array_primitive_value -%type expression_list -%type lower_element -%type upper_element -%type first_element -%type mode_argument -%type upper_lower_argument -%type length_argument -%type array_mode_name -%type string_mode_name -%type variant_structure_mode_name -%type boolean_expression -%type case_selector_list -%type subexpression -%type case_label_specification -%type buffer_location -%type single_assignment_action -%type mode_name - -%% - -/* Z.200, 5.3.1 */ - -start : value { } - | mode_name - { write_exp_elt_opcode(OP_TYPE); - write_exp_elt_type($1.type); - write_exp_elt_opcode(OP_TYPE);} - ; - -value : expression - { - $$ = 0; /* FIXME */ - } - | undefined_value - { - $$ = 0; /* FIXME */ - } - ; - -undefined_value : FIXME_01 - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 4.2.1 */ - -location : access_name - | primitive_value POINTER - { - write_exp_elt_opcode (UNOP_IND); - } - ; - -/* Z.200, 4.2.2 */ - -access_name : LOCATION_NAME - { - write_exp_elt_opcode (OP_VAR_VALUE); - write_exp_elt_block (NULL); - write_exp_elt_sym ($1.sym); - write_exp_elt_opcode (OP_VAR_VALUE); - } - | GDB_LAST /* gdb specific */ - { - write_exp_elt_opcode (OP_LAST); - write_exp_elt_longcst ($1); - write_exp_elt_opcode (OP_LAST); - } - | GDB_REGNAME /* gdb specific */ - { - write_exp_elt_opcode (OP_REGISTER); - write_exp_elt_longcst ($1); - write_exp_elt_opcode (OP_REGISTER); - } - | GDB_VARIABLE /* gdb specific */ - { - write_exp_elt_opcode (OP_INTERNALVAR); - write_exp_elt_intern ($1); - write_exp_elt_opcode (OP_INTERNALVAR); - } - | FIXME_03 - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 4.2.8 */ - -expression_list : expression - { - arglist_len = 1; - } - | expression_list ',' expression - { - arglist_len++; - } - -/* Z.200, 5.2.1 */ - -primitive_value : location_contents - { - $$ = 0; /* FIXME */ - } - | value_name - { - $$ = 0; /* FIXME */ - } - | literal - { - $$ = 0; /* FIXME */ - } - | tuple - { - $$ = 0; /* FIXME */ - } - | value_string_element - { - $$ = 0; /* FIXME */ - } - | value_string_slice - { - $$ = 0; /* FIXME */ - } - | value_array_element - { - $$ = 0; /* FIXME */ - } - | value_array_slice - { - $$ = 0; /* FIXME */ - } - | value_structure_field - { - $$ = 0; /* FIXME */ - } - | expression_conversion - { - $$ = 0; /* FIXME */ - } - | value_procedure_call - { - $$ = 0; /* FIXME */ - } - | value_built_in_routine_call - { - $$ = 0; /* FIXME */ - } - | start_expression - { - $$ = 0; /* FIXME */ - } - | zero_adic_operator - { - $$ = 0; /* FIXME */ - } - | parenthesised_expression - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.2.2 */ - -location_contents: location - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.2.3 */ - -value_name : synonym_name - { - $$ = 0; /* FIXME */ - } - | value_enumeration_name - { - $$ = 0; /* FIXME */ - } - | value_do_with_name - { - $$ = 0; /* FIXME */ - } - | value_receive_name - { - $$ = 0; /* FIXME */ - } - | GENERAL_PROCEDURE_NAME - { - write_exp_elt_opcode (OP_VAR_VALUE); - write_exp_elt_block (NULL); - write_exp_elt_sym ($1.sym); - write_exp_elt_opcode (OP_VAR_VALUE); - } - ; - -/* Z.200, 5.2.4.1 */ - -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); - } - | BOOLEAN_LITERAL - { - write_exp_elt_opcode (OP_BOOL); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_BOOL); - } - | CHARACTER_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); - } - | FLOAT_LITERAL - { - write_exp_elt_opcode (OP_DOUBLE); - write_exp_elt_type (builtin_type_double); - write_exp_elt_dblcst ($1); - write_exp_elt_opcode (OP_DOUBLE); - } - | SET_LITERAL - { - $$ = 0; /* FIXME */ - } - | EMPTINESS_LITERAL - { - $$ = 0; /* FIXME */ - } - | CHARACTER_STRING_LITERAL - { - write_exp_elt_opcode (OP_STRING); - write_exp_string ($1); - write_exp_elt_opcode (OP_STRING); - } - | BIT_STRING_LITERAL - { - write_exp_elt_opcode (OP_BITSTRING); - write_exp_bitstring ($1); - write_exp_elt_opcode (OP_BITSTRING); - } - ; - -/* Z.200, 5.2.5 */ - -tuple : FIXME_04 - { - $$ = 0; /* FIXME */ - } - ; - - -/* Z.200, 5.2.6 */ - -value_string_element: string_primitive_value '(' start_element ')' - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.2.7 */ - -value_string_slice: string_primitive_value '(' left_element ':' right_element ')' - { - $$ = 0; /* FIXME */ - } - | string_primitive_value '(' start_element UP slice_size ')' - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.2.8 */ - -value_array_element: array_primitive_value '(' - /* This is to save the value of arglist_len - being accumulated for each dimension. */ - { start_arglist (); } - expression_list ')' - { - write_exp_elt_opcode (MULTI_SUBSCRIPT); - write_exp_elt_longcst ((LONGEST) end_arglist ()); - write_exp_elt_opcode (MULTI_SUBSCRIPT); - } - ; - -/* Z.200, 5.2.9 */ - -value_array_slice: array_primitive_value '(' lower_element ':' upper_element ')' - { - $$ = 0; /* FIXME */ - } - | array_primitive_value '(' first_element UP slice_size ')' - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.2.10 */ - -value_structure_field: primitive_value FIELD_NAME - { write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string ($2); - write_exp_elt_opcode (STRUCTOP_STRUCT); - } - ; - -/* Z.200, 5.2.11 */ - -expression_conversion: mode_name parenthesised_expression - { - write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type ($1.type); - write_exp_elt_opcode (UNOP_CAST); - } - ; - -/* Z.200, 5.2.12 */ - -value_procedure_call: FIXME_05 - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.2.13 */ - -value_built_in_routine_call: chill_value_built_in_routine_call - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.2.14 */ - -start_expression: FIXME_06 - { - $$ = 0; /* FIXME */ - } /* Not in GNU-Chill */ - ; - -/* Z.200, 5.2.15 */ - -zero_adic_operator: FIXME_07 - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.2.16 */ - -parenthesised_expression: '(' expression ')' - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.3.2 */ - -expression : operand_0 - { - $$ = 0; /* FIXME */ - } - | single_assignment_action - { - $$ = 0; /* FIXME */ - } - | conditional_expression - { - $$ = 0; /* FIXME */ - } - ; - -conditional_expression : IF boolean_expression then_alternative else_alternative FI - { - $$ = 0; /* FIXME */ - } - | CASE case_selector_list OF value_case_alternative '[' ELSE sub_expression ']' ESAC - { - $$ = 0; /* FIXME */ - } - ; - -then_alternative: THEN subexpression - { - $$ = 0; /* FIXME */ - } - ; - -else_alternative: ELSE subexpression - { - $$ = 0; /* FIXME */ - } - | ELSIF boolean_expression then_alternative else_alternative - { - $$ = 0; /* FIXME */ - } - ; - -sub_expression : expression - { - $$ = 0; /* FIXME */ - } - ; - -value_case_alternative: case_label_specification ':' sub_expression ';' - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.3.3 */ - -operand_0 : operand_1 - { - $$ = 0; /* FIXME */ - } - | operand_0 LOGIOR operand_1 - { - write_exp_elt_opcode (BINOP_BITWISE_IOR); - } - | operand_0 ORIF operand_1 - { - $$ = 0; /* FIXME */ - } - | operand_0 LOGXOR operand_1 - { - write_exp_elt_opcode (BINOP_BITWISE_XOR); - } - ; - -/* Z.200, 5.3.4 */ - -operand_1 : operand_2 - { - $$ = 0; /* FIXME */ - } - | operand_1 LOGAND operand_2 - { - write_exp_elt_opcode (BINOP_BITWISE_AND); - } - | operand_1 ANDIF operand_2 - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 5.3.5 */ - -operand_2 : operand_3 - { - $$ = 0; /* FIXME */ - } - | operand_2 '=' operand_3 - { - write_exp_elt_opcode (BINOP_EQUAL); - } - | operand_2 NOTEQUAL operand_3 - { - write_exp_elt_opcode (BINOP_NOTEQUAL); - } - | operand_2 '>' operand_3 - { - write_exp_elt_opcode (BINOP_GTR); - } - | operand_2 GTR operand_3 - { - write_exp_elt_opcode (BINOP_GEQ); - } - | operand_2 '<' operand_3 - { - write_exp_elt_opcode (BINOP_LESS); - } - | operand_2 LEQ operand_3 - { - write_exp_elt_opcode (BINOP_LEQ); - } - | operand_2 IN operand_3 - { - $$ = 0; /* FIXME */ - } - ; - - -/* Z.200, 5.3.6 */ - -operand_3 : operand_4 - { - $$ = 0; /* FIXME */ - } - | operand_3 '+' operand_4 - { - write_exp_elt_opcode (BINOP_ADD); - } - | operand_3 '-' operand_4 - { - write_exp_elt_opcode (BINOP_SUB); - } - | operand_3 SLASH_SLASH operand_4 - { - write_exp_elt_opcode (BINOP_CONCAT); - } - ; - -/* Z.200, 5.3.7 */ - -operand_4 : operand_5 - { - $$ = 0; /* FIXME */ - } - | operand_4 '*' operand_5 - { - write_exp_elt_opcode (BINOP_MUL); - } - | operand_4 '/' operand_5 - { - write_exp_elt_opcode (BINOP_DIV); - } - | operand_4 MOD operand_5 - { - write_exp_elt_opcode (BINOP_MOD); - } - | operand_4 REM operand_5 - { - write_exp_elt_opcode (BINOP_REM); - } - ; - -/* Z.200, 5.3.8 */ - -operand_5 : operand_6 - { - $$ = 0; /* FIXME */ - } - | '-' operand_6 - { - write_exp_elt_opcode (UNOP_NEG); - } - | NOT operand_6 - { - write_exp_elt_opcode (UNOP_LOGICAL_NOT); - } - | parenthesised_expression literal -/* We require the string operand to be a literal, to avoid some - nasty parsing ambiguities. */ - { - write_exp_elt_opcode (BINOP_CONCAT); - } - ; - -/* Z.200, 5.3.9 */ - -operand_6 : POINTER location - { - write_exp_elt_opcode (UNOP_ADDR); - } - | RECEIVE buffer_location - { - $$ = 0; /* FIXME */ - } - | primitive_value - { - $$ = 0; /* FIXME */ - } - ; - - -/* Z.200, 6.2 */ - -single_assignment_action : - location GDB_ASSIGNMENT value - { - write_exp_elt_opcode (BINOP_ASSIGN); - } - ; - -/* Z.200, 6.20.3 */ - -chill_value_built_in_routine_call : - NUM '(' expression ')' - { - $$ = 0; /* FIXME */ - } - | PRED '(' expression ')' - { - $$ = 0; /* FIXME */ - } - | SUCC '(' expression ')' - { - $$ = 0; /* FIXME */ - } - | ABS '(' expression ')' - { - $$ = 0; /* FIXME */ - } - | CARD '(' expression ')' - { - $$ = 0; /* FIXME */ - } - | MAX_TOKEN '(' expression ')' - { - $$ = 0; /* FIXME */ - } - | MIN_TOKEN '(' expression ')' - { - $$ = 0; /* FIXME */ - } - | SIZE '(' location ')' - { - $$ = 0; /* FIXME */ - } - | SIZE '(' mode_argument ')' - { - $$ = 0; /* FIXME */ - } - | UPPER '(' upper_lower_argument ')' - { - $$ = 0; /* FIXME */ - } - | LOWER '(' upper_lower_argument ')' - { - $$ = 0; /* FIXME */ - } - | LENGTH '(' length_argument ')' - { - $$ = 0; /* FIXME */ - } - ; - -mode_argument : mode_name - { - $$ = 0; /* FIXME */ - } - | array_mode_name '(' expression ')' - { - $$ = 0; /* FIXME */ - } - | string_mode_name '(' expression ')' - { - $$ = 0; /* FIXME */ - } - | variant_structure_mode_name '(' expression_list ')' - { - $$ = 0; /* FIXME */ - } - ; - -mode_name : TYPENAME - ; - -upper_lower_argument : expression - { - $$ = 0; /* FIXME */ - } - | mode_name - { - $$ = 0; /* FIXME */ - } - ; - -length_argument : expression - { - $$ = 0; /* FIXME */ - } - ; - -/* Z.200, 12.4.3 */ - -array_primitive_value : primitive_value - { - $$ = 0; - } - ; - - -/* Things which still need productions... */ - -array_mode_name : FIXME_08 { $$ = 0; } -string_mode_name : FIXME_09 { $$ = 0; } -variant_structure_mode_name: FIXME_10 { $$ = 0; } -synonym_name : FIXME_11 { $$ = 0; } -value_enumeration_name : FIXME_12 { $$ = 0; } -value_do_with_name : FIXME_13 { $$ = 0; } -value_receive_name : FIXME_14 { $$ = 0; } -string_primitive_value : FIXME_15 { $$ = 0; } -start_element : FIXME_16 { $$ = 0; } -left_element : FIXME_17 { $$ = 0; } -right_element : FIXME_18 { $$ = 0; } -slice_size : FIXME_19 { $$ = 0; } -lower_element : FIXME_20 { $$ = 0; } -upper_element : FIXME_21 { $$ = 0; } -first_element : FIXME_22 { $$ = 0; } -boolean_expression : FIXME_26 { $$ = 0; } -case_selector_list : FIXME_27 { $$ = 0; } -subexpression : FIXME_28 { $$ = 0; } -case_label_specification: FIXME_29 { $$ = 0; } -buffer_location : FIXME_30 { $$ = 0; } - -%% - -/* Implementation of a dynamically expandable buffer for processing input - characters acquired through lexptr and building a value to return in - yylval. */ - -static char *tempbuf; /* Current buffer contents */ -static int tempbufsize; /* Size of allocated buffer */ -static int tempbufindex; /* Current index into buffer */ - -#define GROWBY_MIN_SIZE 64 /* Minimum amount to grow buffer by */ - -#define CHECKBUF(size) \ - do { \ - if (tempbufindex + (size) >= tempbufsize) \ - { \ - growbuf_by_size (size); \ - } \ - } while (0); - -/* Grow the static temp buffer if necessary, including allocating the first one - on demand. */ - -static void -growbuf_by_size (count) - int count; -{ - int growby; - - growby = max (count, GROWBY_MIN_SIZE); - tempbufsize += growby; - if (tempbuf == NULL) - { - tempbuf = (char *) malloc (tempbufsize); - } - else - { - tempbuf = (char *) realloc (tempbuf, tempbufsize); - } -} - -/* Try to consume a simple name string token. If successful, returns - a pointer to a nullbyte terminated copy of the name that can be used - in symbol table lookups. If not successful, returns NULL. */ - -static char * -match_simple_name_string () -{ - char *tokptr = lexptr; - - if (isalpha (*tokptr)) - { - char *result; - do { - tokptr++; - } while (isalnum (*tokptr) || (*tokptr == '_')); - yylval.sval.ptr = lexptr; - yylval.sval.length = tokptr - lexptr; - lexptr = tokptr; - result = copy_name (yylval.sval); - for (tokptr = result; *tokptr; tokptr++) - if (isupper (*tokptr)) - *tokptr = tolower(*tokptr); - return result; - } - return (NULL); -} - -/* Start looking for a value composed of valid digits as set by the base - in use. Note that '_' characters are valid anywhere, in any quantity, - and are simply ignored. Since we must find at least one valid digit, - or reject this token as an integer literal, we keep track of how many - digits we have encountered. */ - -static int -decode_integer_value (base, tokptrptr, ivalptr) - int base; - char **tokptrptr; - int *ivalptr; -{ - char *tokptr = *tokptrptr; - int temp; - int digits = 0; - - while (*tokptr != '\0') - { - temp = tolower (*tokptr); - tokptr++; - switch (temp) - { - case '_': - continue; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - temp -= '0'; - break; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - temp -= 'a'; - temp += 10; - break; - default: - temp = base; - break; - } - if (temp < base) - { - digits++; - *ivalptr *= base; - *ivalptr += temp; - } - else - { - /* Found something not in domain for current base. */ - tokptr--; /* Unconsume what gave us indigestion. */ - break; - } - } - - /* If we didn't find any digits, then we don't have a valid integer - value, so reject the entire token. Otherwise, update the lexical - scan pointer, and return non-zero for success. */ - - if (digits == 0) - { - return (0); - } - else - { - *tokptrptr = tokptr; - return (1); - } -} - -static int -decode_integer_literal (valptr, tokptrptr) - int *valptr; - char **tokptrptr; -{ - char *tokptr = *tokptrptr; - int base = 0; - int ival = 0; - int explicit_base = 0; - - /* Look for an explicit base specifier, which is optional. */ - - switch (*tokptr) - { - case 'd': - case 'D': - explicit_base++; - base = 10; - tokptr++; - break; - case 'b': - case 'B': - explicit_base++; - base = 2; - tokptr++; - break; - case 'h': - case 'H': - explicit_base++; - base = 16; - tokptr++; - break; - case 'o': - case 'O': - explicit_base++; - base = 8; - tokptr++; - break; - default: - base = 10; - break; - } - - /* If we found an explicit base ensure that the character after the - explicit base is a single quote. */ - - if (explicit_base && (*tokptr++ != '\'')) - { - return (0); - } - - /* Attempt to decode whatever follows as an integer value in the - indicated base, updating the token pointer in the process and - computing the value into ival. Also, if we have an explicit - base, then the next character must not be a single quote, or we - have a bitstring literal, so reject the entire token in this case. - Otherwise, update the lexical scan pointer, and return non-zero - for success. */ - - if (!decode_integer_value (base, &tokptr, &ival)) - { - return (0); - } - else if (explicit_base && (*tokptr == '\'')) - { - return (0); - } - else - { - *valptr = ival; - *tokptrptr = tokptr; - return (1); - } -} - -/* If it wasn't for the fact that floating point values can contain '_' - characters, we could just let strtod do all the hard work by letting it - try to consume as much of the current token buffer as possible and - find a legal conversion. Unfortunately we need to filter out the '_' - characters before calling strtod, which we do by copying the other - legal chars to a local buffer to be converted. However since we also - need to keep track of where the last unconsumed character in the input - buffer is, we have transfer only as many characters as may compose a - legal floating point value. */ - -static int -match_float_literal () -{ - char *tokptr = lexptr; - char *buf; - char *copy; - double dval; - extern double strtod (); - - /* Make local buffer in which to build the string to convert. This is - required because underscores are valid in chill floating point numbers - but not in the string passed to strtod to convert. The string will be - no longer than our input string. */ - - copy = buf = (char *) alloca (strlen (tokptr) + 1); - - /* Transfer all leading digits to the conversion buffer, discarding any - underscores. */ - - while (isdigit (*tokptr) || *tokptr == '_') - { - if (*tokptr != '_') - { - *copy++ = *tokptr; - } - tokptr++; - } - - /* Now accept either a '.', or one of [eEdD]. Dot is legal regardless - of whether we found any leading digits, and we simply accept it and - continue on to look for the fractional part and/or exponent. One of - [eEdD] is legal only if we have seen digits, and means that there - is no fractional part. If we find neither of these, then this is - not a floating point number, so return failure. */ - - switch (*tokptr++) - { - case '.': - /* Accept and then look for fractional part and/or exponent. */ - *copy++ = '.'; - break; - - case 'e': - case 'E': - case 'd': - case 'D': - if (copy == buf) - { - return (0); - } - *copy++ = 'e'; - goto collect_exponent; - break; - - default: - return (0); - break; - } - - /* We found a '.', copy any fractional digits to the conversion buffer, up - to the first nondigit, non-underscore character. */ - - while (isdigit (*tokptr) || *tokptr == '_') - { - if (*tokptr != '_') - { - *copy++ = *tokptr; - } - tokptr++; - } - - /* Look for an exponent, which must start with one of [eEdD]. If none - is found, jump directly to trying to convert what we have collected - so far. */ - - switch (*tokptr) - { - case 'e': - case 'E': - case 'd': - case 'D': - *copy++ = 'e'; - tokptr++; - break; - default: - goto convert_float; - break; - } - - /* Accept an optional '-' or '+' following one of [eEdD]. */ - - collect_exponent: - if (*tokptr == '+' || *tokptr == '-') - { - *copy++ = *tokptr++; - } - - /* Now copy an exponent into the conversion buffer. Note that at the - moment underscores are *not* allowed in exponents. */ - - while (isdigit (*tokptr)) - { - *copy++ = *tokptr++; - } - - /* If we transfered any chars to the conversion buffer, try to interpret its - contents as a floating point value. If any characters remain, then we - must not have a valid floating point string. */ - - convert_float: - *copy = '\0'; - if (copy != buf) - { - dval = strtod (buf, ©); - if (*copy == '\0') - { - yylval.dval = dval; - lexptr = tokptr; - return (FLOAT_LITERAL); - } - } - return (0); -} - -/* Recognize a string literal. A string literal is a nonzero sequence - of characters enclosed in matching single or double quotes, except that - a single character inside single quotes is a character literal, which - we reject as a string literal. To embed the terminator character inside - a string, it is simply doubled (I.E. "this""is""one""string") */ - -static int -match_string_literal () -{ - char *tokptr = lexptr; - - for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++) - { - CHECKBUF (1); - if (*tokptr == *lexptr) - { - if (*(tokptr + 1) == *lexptr) - { - tokptr++; - } - else - { - break; - } - } - tempbuf[tempbufindex++] = *tokptr; - } - if (*tokptr == '\0' /* no terminator */ - || tempbufindex == 0 /* no string */ - || (tempbufindex == 1 && *tokptr == '\'')) /* char literal */ - { - return (0); - } - else - { - tempbuf[tempbufindex] = '\0'; - yylval.sval.ptr = tempbuf; - yylval.sval.length = tempbufindex; - lexptr = ++tokptr; - return (CHARACTER_STRING_LITERAL); - } -} - -/* Recognize a character literal. A character literal is single character - or a control sequence, enclosed in single quotes. A control sequence - is a comma separated list of one or more integer literals, enclosed - in parenthesis and introduced with a circumflex character. - - EX: 'a' '^(7)' '^(7,8)' - - As a GNU chill extension, the syntax C'xx' is also recognized as a - character literal, where xx is a hex value for the character. - - Note that more than a single character, enclosed in single quotes, is - a string literal. - - Also note that the control sequence form is not in GNU Chill since it - is ambiguous with the string literal form using single quotes. I.E. - is '^(7)' a character literal or a string literal. In theory it it - possible to tell by context, but GNU Chill doesn't accept the control - sequence form, so neither do we (for now the code is disabled). - - Returns CHARACTER_LITERAL if a match is found. - */ - -static int -match_character_literal () -{ - char *tokptr = lexptr; - int ival = 0; - - if ((tolower (*tokptr) == 'c') && (*(tokptr + 1) == '\'')) - { - /* We have a GNU chill extension form, so skip the leading "C'", - decode the hex value, and then ensure that we have a trailing - single quote character. */ - tokptr += 2; - if (!decode_integer_value (16, &tokptr, &ival) || (*tokptr != '\'')) - { - return (0); - } - tokptr++; - } - else if (*tokptr == '\'') - { - tokptr++; - - /* Determine which form we have, either a control sequence or the - single character form. */ - - if ((*tokptr == '^') && (*(tokptr + 1) == '(')) - { -#if 0 /* Disable, see note above. -fnf */ - /* Match and decode a control sequence. Return zero if we don't - find a valid integer literal, or if the next unconsumed character - after the integer literal is not the trailing ')'. - FIXME: We currently don't handle the multiple integer literal - form. */ - tokptr += 2; - if (!decode_integer_literal (&ival, &tokptr) || (*tokptr++ != ')')) - { - return (0); - } -#else - return (0); -#endif - } - else - { - ival = *tokptr++; - } - - /* The trailing quote has not yet been consumed. If we don't find - it, then we have no match. */ - - if (*tokptr++ != '\'') - { - return (0); - } - } - else - { - /* Not a character literal. */ - return (0); - } - yylval.typed_val.val = ival; - yylval.typed_val.type = builtin_type_chill_char; - lexptr = tokptr; - return (CHARACTER_LITERAL); -} - -/* Recognize an integer literal, as specified in Z.200 sec 5.2.4.2. - Note that according to 5.2.4.2, a single "_" is also a valid integer - literal, however GNU-chill requires there to be at least one "digit" - in any integer literal. */ - -static int -match_integer_literal () -{ - char *tokptr = lexptr; - int ival; - - if (!decode_integer_literal (&ival, &tokptr)) - { - return (0); - } - else - { - yylval.typed_val.val = ival; - yylval.typed_val.type = builtin_type_int; - lexptr = tokptr; - return (INTEGER_LITERAL); - } -} - -/* Recognize a bit-string literal, as specified in Z.200 sec 5.2.4.8 - Note that according to 5.2.4.8, a single "_" is also a valid bit-string - literal, however GNU-chill requires there to be at least one "digit" - in any bit-string literal. */ - -static int -match_bitstring_literal () -{ - char *tokptr = lexptr; - int mask; - int bitoffset = 0; - int bitcount = 0; - int base; - int digit; - - tempbufindex = 0; - - /* Look for the required explicit base specifier. */ - - switch (*tokptr++) - { - case 'b': - case 'B': - base = 2; - break; - case 'o': - case 'O': - base = 8; - break; - case 'h': - case 'H': - base = 16; - break; - default: - return (0); - break; - } - - /* Ensure that the character after the explicit base is a single quote. */ - - if (*tokptr++ != '\'') - { - return (0); - } - - while (*tokptr != '\0' && *tokptr != '\'') - { - digit = tolower (*tokptr); - tokptr++; - switch (digit) - { - case '_': - continue; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - digit -= '0'; - break; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - digit -= 'a'; - digit += 10; - break; - default: - return (0); - break; - } - if (digit >= base) - { - /* Found something not in domain for current base. */ - return (0); - } - else - { - /* Extract bits from digit, starting with the msbit appropriate for - the current base, and packing them into the bitstring byte, - starting at the lsbit. */ - for (mask = (base >> 1); mask > 0; mask >>= 1) - { - bitcount++; - CHECKBUF (1); - if (digit & mask) - { - tempbuf[tempbufindex] |= (1 << bitoffset); - } - bitoffset++; - if (bitoffset == HOST_CHAR_BIT) - { - bitoffset = 0; - tempbufindex++; - } - } - } - } - - /* Verify that we consumed everything up to the trailing single quote, - and that we found some bits (IE not just underbars). */ - - if (*tokptr++ != '\'') - { - return (0); - } - else - { - yylval.sval.ptr = tempbuf; - yylval.sval.length = bitcount; - lexptr = tokptr; - return (BIT_STRING_LITERAL); - } -} - -/* Recognize tokens that start with '$'. These include: - - $regname A native register name or a "standard - register name". - Return token GDB_REGNAME. - - $variable A convenience variable with a name chosen - by the user. - Return token GDB_VARIABLE. - - $digits Value history with index , starting - from the first value which has index 1. - Return GDB_LAST. - - $$digits Value history with index relative - to the last value. I.E. $$0 is the last - value, $$1 is the one previous to that, $$2 - is the one previous to $$1, etc. - Return token GDB_LAST. - - $ | $0 | $$0 The last value in the value history. - Return token GDB_LAST. - - $$ An abbreviation for the second to the last - value in the value history, I.E. $$1 - Return token GDB_LAST. - - Note that we currently assume that register names and convenience - variables follow the convention of starting with a letter or '_'. - - */ - -static int -match_dollar_tokens () -{ - char *tokptr; - int regno; - int namelength; - int negate; - int ival; - - /* We will always have a successful match, even if it is just for - a single '$', the abbreviation for $$0. So advance lexptr. */ - - tokptr = ++lexptr; - - if (*tokptr == '_' || isalpha (*tokptr)) - { - /* Look for a match with a native register name, usually something - like "r0" for example. */ - - for (regno = 0; regno < NUM_REGS; regno++) - { - namelength = strlen (reg_names[regno]); - if (STREQN (tokptr, reg_names[regno], namelength) - && !isalnum (tokptr[namelength])) - { - yylval.lval = regno; - lexptr += namelength + 1; - return (GDB_REGNAME); - } - } - - /* Look for a match with a standard register name, usually something - like "pc", which gdb always recognizes as the program counter - regardless of what the native register name is. */ - - for (regno = 0; regno < num_std_regs; regno++) - { - namelength = strlen (std_regs[regno].name); - if (STREQN (tokptr, std_regs[regno].name, namelength) - && !isalnum (tokptr[namelength])) - { - yylval.lval = std_regs[regno].regnum; - lexptr += namelength; - return (GDB_REGNAME); - } - } - - /* Attempt to match against a convenience variable. Note that - this will always succeed, because if no variable of that name - already exists, the lookup_internalvar will create one for us. - Also note that both lexptr and tokptr currently point to the - start of the input string we are trying to match, and that we - have already tested the first character for non-numeric, so we - don't have to treat it specially. */ - - while (*tokptr == '_' || isalnum (*tokptr)) - { - tokptr++; - } - yylval.sval.ptr = lexptr; - yylval.sval.length = tokptr - lexptr; - yylval.ivar = lookup_internalvar (copy_name (yylval.sval)); - lexptr = tokptr; - return (GDB_VARIABLE); - } - - /* Since we didn't match against a register name or convenience - variable, our only choice left is a history value. */ - - if (*tokptr == '$') - { - negate = 1; - ival = 1; - tokptr++; - } - else - { - negate = 0; - ival = 0; - } - - /* Attempt to decode more characters as an integer value giving - the index in the history list. If successful, the value will - overwrite ival (currently 0 or 1), and if not, ival will be - left alone, which is good since it is currently correct for - the '$' or '$$' case. */ - - decode_integer_literal (&ival, &tokptr); - yylval.lval = negate ? -ival : ival; - lexptr = tokptr; - return (GDB_LAST); -} - -struct token -{ - char *operator; - int token; -}; - -static const struct token idtokentab[] = -{ - { "length", LENGTH }, - { "lower", LOWER }, - { "upper", UPPER }, - { "andif", ANDIF }, - { "pred", PRED }, - { "succ", SUCC }, - { "card", CARD }, - { "size", SIZE }, - { "orif", ORIF }, - { "num", NUM }, - { "abs", ABS }, - { "max", MAX_TOKEN }, - { "min", MIN_TOKEN }, - { "mod", MOD }, - { "rem", REM }, - { "not", NOT }, - { "xor", LOGXOR }, - { "and", LOGAND }, - { "in", IN }, - { "or", LOGIOR } -}; - -static const struct token tokentab2[] = -{ - { ":=", GDB_ASSIGNMENT }, - { "//", SLASH_SLASH }, - { "->", POINTER }, - { "/=", NOTEQUAL }, - { "<=", LEQ }, - { ">=", GTR } -}; - -/* Read one token, getting characters through lexptr. */ -/* This is where we will check to make sure that the language and the - operators used are compatible. */ - -static int -yylex () -{ - unsigned int i; - int token; - char *simplename; - struct symbol *sym; - - /* Skip over any leading whitespace. */ - while (isspace (*lexptr)) - { - lexptr++; - } - /* Look for special single character cases which can't be the first - character of some other multicharacter token. */ - switch (*lexptr) - { - case '\0': - return (0); - case ',': - case '=': - case ';': - case '!': - case '+': - case '*': - case '(': - case ')': - case '[': - case ']': - return (*lexptr++); - } - /* Look for characters which start a particular kind of multicharacter - token, such as a character literal, register name, convenience - variable name, string literal, etc. */ - switch (*lexptr) - { - case '\'': - case '\"': - /* First try to match a string literal, which is any nonzero - sequence of characters enclosed in matching single or double - quotes, except that a single character inside single quotes - is a character literal, so we have to catch that case also. */ - token = match_string_literal (); - if (token != 0) - { - return (token); - } - if (*lexptr == '\'') - { - token = match_character_literal (); - if (token != 0) - { - return (token); - } - } - break; - case 'C': - case 'c': - token = match_character_literal (); - if (token != 0) - { - return (token); - } - break; - case '$': - token = match_dollar_tokens (); - if (token != 0) - { - return (token); - } - break; - } - /* See if it is a special token of length 2. */ - for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++) - { - if (STREQN (lexptr, tokentab2[i].operator, 2)) - { - lexptr += 2; - return (tokentab2[i].token); - } - } - /* Look for single character cases which which could be the first - character of some other multicharacter token, but aren't, or we - would already have found it. */ - switch (*lexptr) - { - case '-': - case ':': - case '/': - case '<': - case '>': - return (*lexptr++); - } - /* Look for a float literal before looking for an integer literal, so - we match as much of the input stream as possible. */ - token = match_float_literal (); - if (token != 0) - { - return (token); - } - token = match_bitstring_literal (); - if (token != 0) - { - return (token); - } - token = match_integer_literal (); - if (token != 0) - { - return (token); - } - - /* Try to match a simple name string, and if a match is found, then - further classify what sort of name it is and return an appropriate - token. Note that attempting to match a simple name string consumes - the token from lexptr, so we can't back out if we later find that - we can't classify what sort of name it is. */ - - simplename = match_simple_name_string (); - - if (simplename != NULL) - { - /* See if it is a reserved identifier. */ - for (i = 0; i < sizeof (idtokentab) / sizeof (idtokentab[0]); i++) - { - if (STREQ (simplename, idtokentab[i].operator)) - { - return (idtokentab[i].token); - } - } - - /* Look for other special tokens. */ - if (STREQ (simplename, "true")) - { - yylval.ulval = 1; - return (BOOLEAN_LITERAL); - } - if (STREQ (simplename, "false")) - { - yylval.ulval = 0; - return (BOOLEAN_LITERAL); - } - - sym = lookup_symbol (simplename, expression_context_block, - VAR_NAMESPACE, (int *) NULL, - (struct symtab **) NULL); - if (sym != NULL) - { - yylval.ssym.stoken.ptr = NULL; - yylval.ssym.stoken.length = 0; - yylval.ssym.sym = sym; - yylval.ssym.is_a_field_of_this = 0; /* FIXME, C++'ism */ - switch (SYMBOL_CLASS (sym)) - { - case LOC_BLOCK: - /* Found a procedure name. */ - return (GENERAL_PROCEDURE_NAME); - case LOC_STATIC: - /* Found a global or local static variable. */ - return (LOCATION_NAME); - case LOC_REGISTER: - case LOC_ARG: - case LOC_REF_ARG: - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_LOCAL: - case LOC_LOCAL_ARG: - case LOC_BASEREG: - case LOC_BASEREG_ARG: - if (innermost_block == NULL - || contained_in (block_found, innermost_block)) - { - innermost_block = block_found; - } - return (LOCATION_NAME); - break; - case LOC_CONST: - case LOC_LABEL: - return (LOCATION_NAME); - break; - case LOC_TYPEDEF: - yylval.tsym.type = SYMBOL_TYPE (sym); - return TYPENAME; - case LOC_UNDEF: - case LOC_CONST_BYTES: - case LOC_OPTIMIZED_OUT: - error ("Symbol \"%s\" names no location.", simplename); - break; - } - } - 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.", simplename); - } - } - - /* Catch single character tokens which are not part of some - longer token. */ - - switch (*lexptr) - { - case '.': /* Not float for example. */ - lexptr++; - while (isspace (*lexptr)) lexptr++; - simplename = match_simple_name_string (); - if (!simplename) - return '.'; - return FIELD_NAME; - } - - return (ILLEGAL_TOKEN); -} - -void -yyerror (msg) - char *msg; /* unused */ -{ - printf ("Parsing: %s\n", lexptr); - if (yychar < 256) - { - error ("Invalid syntax in expression near character '%c'.", yychar); - } - else - { - error ("Invalid syntax in expression"); - } -} diff --git a/gnu/usr.bin/gdb/gdb/ch-lang.c b/gnu/usr.bin/gdb/gdb/ch-lang.c deleted file mode 100644 index 1ffb8d7..0000000 --- a/gnu/usr.bin/gdb/gdb/ch-lang.c +++ /dev/null @@ -1,355 +0,0 @@ -/* Chill language support routines for GDB, the GNU debugger. - Copyright 1992 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 "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "parser-defs.h" -#include "language.h" -#include "ch-lang.h" - - -/* For now, Chill uses a simple mangling algorithm whereby you simply - discard everything after the occurance of two successive CPLUS_MARKER - characters to derive the demangled form. */ - -char * -chill_demangle (mangled) - const char *mangled; -{ - char *joiner; - char *demangled; - - joiner = strchr (mangled, CPLUS_MARKER); - if (joiner != NULL && *(joiner + 1) == CPLUS_MARKER) - { - demangled = savestring (mangled, joiner - mangled); - } - else - { - demangled = NULL; - } - return (demangled); -} - -static void -chill_printchar (c, stream) - register int c; - GDB_FILE *stream; -{ - c &= 0xFF; /* Avoid sign bit follies */ - - if (PRINT_LITERAL_FORM (c)) - { - fprintf_filtered (stream, "'%c'", c); - } - else - { - fprintf_filtered (stream, "C'%.2x'", (unsigned int) c); - } -} - -/* 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. - Note that gdb maintains the length of strings without counting the - terminating null byte, while chill strings are typically written with - an explicit null byte. So we always assume an implied null byte - until gdb is able to maintain non-null terminated strings as well - as null terminated strings (FIXME). - */ - -static void -chill_printstr (stream, string, length, force_ellipses) - GDB_FILE *stream; - char *string; - unsigned int length; - int force_ellipses; -{ - register unsigned int i; - unsigned int things_printed = 0; - int in_literal_form = 0; - int in_control_form = 0; - int need_slashslash = 0; - unsigned int c; - extern int repeat_count_threshold; - extern int print_max; - - if (length == 0) - { - fputs_filtered ("\"\"", stream); - return; - } - - for (i = 0; i < length && things_printed < print_max; ++i) - { - /* Position of the character we are examining - to see whether it is repeated. */ - unsigned int rep1; - /* Number of repetitions we have detected so far. */ - unsigned int reps; - - QUIT; - - if (need_slashslash) - { - fputs_filtered ("//", stream); - need_slashslash = 0; - } - - rep1 = i + 1; - reps = 1; - while (rep1 < length && string[rep1] == string[i]) - { - ++rep1; - ++reps; - } - - c = string[i]; - if (reps > repeat_count_threshold) - { - if (in_control_form || in_literal_form) - { - fputs_filtered ("\"//", stream); - in_control_form = in_literal_form = 0; - } - chill_printchar (c, stream); - fprintf_filtered (stream, "", reps); - i = rep1 - 1; - things_printed += repeat_count_threshold; - need_slashslash = 1; - } - else - { - if (PRINT_LITERAL_FORM (c)) - { - if (!in_literal_form) - { - if (in_control_form) - { - fputs_filtered ("\"//", stream); - in_control_form = 0; - } - fputs_filtered ("\"", stream); - in_literal_form = 1; - } - fprintf_filtered (stream, "%c", c); - } - else - { - if (!in_control_form) - { - if (in_literal_form) - { - fputs_filtered ("\"//", stream); - in_literal_form = 0; - } - fputs_filtered ("c\"", stream); - in_control_form = 1; - } - fprintf_filtered (stream, "%.2x", c); - } - ++things_printed; - } - } - - /* Terminate the quotes if necessary. */ - if (in_literal_form || in_control_form) - { - fputs_filtered ("\"", stream); - } - if (force_ellipses || (i < length)) - { - fputs_filtered ("...", stream); - } -} - -/* Return 1 if TYPE is a varying string or array. */ - -int -chill_is_varying_struct (type) - struct type *type; -{ - if (TYPE_CODE (type) != TYPE_CODE_STRUCT) - return 0; - if (TYPE_NFIELDS (type) != 2) - return 0; - if (strcmp (TYPE_FIELD_NAME (type, 0), "__var_length") != 0) - return 0; - return 1; -} - -static struct type * -chill_create_fundamental_type (objfile, typeid) - struct objfile *objfile; - int typeid; -{ - register struct type *type = NULL; - - switch (typeid) - { - default: - /* FIXME: For now, if we are asked to produce a type not in this - language, create the equivalent of a C integer type with the - name "". When all the dust settles from the type - reconstruction work, this should probably become an error. */ - type = init_type (TYPE_CODE_INT, 2, 0, "", objfile); - warning ("internal error: no chill fundamental type %d", typeid); - break; - case FT_VOID: - /* FIXME: Currently the GNU Chill compiler emits some DWARF entries for - typedefs, unrelated to anything directly in the code being compiled, - that have some FT_VOID types. Just fake it for now. */ - type = init_type (TYPE_CODE_VOID, 0, 0, "", objfile); - break; - case FT_BOOLEAN: - type = init_type (TYPE_CODE_BOOL, 1, TYPE_FLAG_UNSIGNED, "BOOL", objfile); - break; - case FT_CHAR: - type = init_type (TYPE_CODE_CHAR, 1, TYPE_FLAG_UNSIGNED, "CHAR", objfile); - break; - case FT_SIGNED_CHAR: - type = init_type (TYPE_CODE_INT, 1, 0, "BYTE", objfile); - break; - case FT_UNSIGNED_CHAR: - type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "UBYTE", objfile); - break; - case FT_SHORT: /* Chill ints are 2 bytes */ - type = init_type (TYPE_CODE_INT, 2, 0, "INT", objfile); - break; - case FT_UNSIGNED_SHORT: /* Chill ints are 2 bytes */ - type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, "UINT", objfile); - break; - case FT_INTEGER: /* FIXME? */ - case FT_SIGNED_INTEGER: /* FIXME? */ - case FT_LONG: /* Chill longs are 4 bytes */ - case FT_SIGNED_LONG: /* Chill longs are 4 bytes */ - type = init_type (TYPE_CODE_INT, 4, 0, "LONG", objfile); - break; - case FT_UNSIGNED_INTEGER: /* FIXME? */ - case FT_UNSIGNED_LONG: /* Chill longs are 4 bytes */ - type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED, "ULONG", objfile); - break; - case FT_FLOAT: - type = init_type (TYPE_CODE_FLT, 4, 0, "REAL", objfile); - break; - case FT_DBL_PREC_FLOAT: - type = init_type (TYPE_CODE_FLT, 8, 0, "LONG_REAL", objfile); - break; - } - return (type); -} - - -/* Table of operators and their precedences for printing expressions. */ - -static const struct op_print chill_op_print_tab[] = { - {"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0}, - {"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0}, - {"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0}, - {"MOD", BINOP_MOD, PREC_MUL, 0}, - {"REM", BINOP_REM, PREC_MUL, 0}, - {":=", BINOP_ASSIGN, PREC_ASSIGN, 1}, - {"=", 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_ADD, PREC_ADD, 0}, - {"-", BINOP_SUB, PREC_ADD, 0}, - {"*", BINOP_MUL, PREC_MUL, 0}, - {"/", BINOP_DIV, PREC_MUL, 0}, - {"//", BINOP_CONCAT, PREC_PREFIX, 0}, /* FIXME: precedence? */ - {"-", UNOP_NEG, PREC_PREFIX, 0}, - {NULL, 0, 0, 0} -}; - - -/* The built-in types of Chill. */ - -struct type *builtin_type_chill_bool; -struct type *builtin_type_chill_char; -struct type *builtin_type_chill_long; -struct type *builtin_type_chill_ulong; -struct type *builtin_type_chill_real; - -struct type ** const (chill_builtin_types[]) = -{ - &builtin_type_chill_bool, - &builtin_type_chill_char, - &builtin_type_chill_long, - &builtin_type_chill_ulong, - &builtin_type_chill_real, - 0 -}; - -const struct language_defn chill_language_defn = { - "chill", - language_chill, - chill_builtin_types, - range_check_on, - type_check_on, - chill_parse, /* parser */ - chill_error, /* parser error function */ - chill_printchar, /* print a character constant */ - chill_printstr, /* function to print a string constant */ - 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 */ - chill_value_print, /* Print a top-levl value */ - &builtin_type_chill_real, /* longest floating point type */ - {"", "B'", "", ""}, /* Binary format info */ - {"O'%lo", "O'", "o", ""}, /* Octal format info */ - {"D'%ld", "D'", "d", ""}, /* Decimal format info */ - {"H'%lx", "H'", "x", ""}, /* Hex format info */ - chill_op_print_tab, /* expression operators for printing */ - LANG_MAGIC -}; - -/* Initialization for Chill */ - -void -_initialize_chill_language () -{ - builtin_type_chill_bool = - init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "BOOL", (struct objfile *) NULL); - builtin_type_chill_char = - init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "CHAR", (struct objfile *) NULL); - builtin_type_chill_long = - init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, - 0, - "LONG", (struct objfile *) NULL); - builtin_type_chill_ulong = - init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "ULONG", (struct objfile *) NULL); - builtin_type_chill_real = - init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, - 0, - "LONG_REAL", (struct objfile *) NULL); - - add_language (&chill_language_defn); -} diff --git a/gnu/usr.bin/gdb/gdb/ch-lang.h b/gnu/usr.bin/gdb/gdb/ch-lang.h deleted file mode 100644 index 0fcb8d6..0000000 --- a/gnu/usr.bin/gdb/gdb/ch-lang.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Chill language support definitions for GDB, the GNU debugger. - Copyright 1992 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. */ - -#ifdef __STDC__ /* Forward decls for prototypes */ -struct value; -#endif - -extern int -chill_parse PARAMS ((void)); /* Defined in ch-exp.y */ - -extern void -chill_error PARAMS ((char *)); /* Defined in ch-exp.y */ - -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, - int, enum val_prettyprint)); - -extern int -chill_value_print PARAMS ((struct value *, GDB_FILE *, - int, enum val_prettyprint)); - -extern int -chill_is_varying_struct PARAMS ((struct type *type)); - - diff --git a/gnu/usr.bin/gdb/gdb/ch-typeprint.c b/gnu/usr.bin/gdb/gdb/ch-typeprint.c deleted file mode 100644 index 9bc4303..0000000 --- a/gnu/usr.bin/gdb/gdb/ch-typeprint.c +++ /dev/null @@ -1,315 +0,0 @@ -/* Support for printing Chill types for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991 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 "defs.h" -#include "obstack.h" -#include "bfd.h" /* Binary File Description */ -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "value.h" -#include "gdbcore.h" -#include "target.h" -#include "command.h" -#include "gdbcmd.h" -#include "language.h" -#include "demangle.h" -#include "ch-lang.h" -#include "typeprint.h" - -#include -#include - -static void -chill_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int)); - -void -chill_print_type (type, varstring, stream, show, level) - struct type *type; - char *varstring; - GDB_FILE *stream; - int show; - int level; -{ - if (varstring != NULL && *varstring != '\0') - { - fputs_filtered (varstring, stream); - fputs_filtered (" ", stream); - } - chill_type_print_base (type, stream, show, level); -} - -/* Print the name of the type (or the ultimate pointer target, - function value or array element). - - SHOW nonzero means don't print this type as just its name; - show its real definition even if it has a name. - SHOW zero means print just typename or tag if there is one - SHOW negative means abbreviate structure elements. - SHOW is decremented for printing of structure elements. - - LEVEL is the depth to indent by. - We increase it for some recursive calls. */ - -static void -chill_type_print_base (type, stream, show, level) - struct type *type; - GDB_FILE *stream; - int show; - int level; -{ - register int len; - register int i; - struct type *index_type; - struct type *range_type; - LONGEST low_bound; - LONGEST high_bound; - - QUIT; - - wrap_here (" "); - if (type == NULL) - { - fputs_filtered ("", 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_stub_type (type); - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_PTR: - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID) - { - fprintf_filtered (stream, "PTR"); - break; - } - fprintf_filtered (stream, "REF "); - chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); - break; - - case TYPE_CODE_BOOL: - /* FIXME: we should probably just print the TYPE_NAME, in case - anyone ever fixes the compiler to give us the real names - in the presence of the chill equivalent of typedef (assuming - there is one). */ - fprintf_filtered (stream, "BOOL"); - break; - - case TYPE_CODE_ARRAY: - range_type = TYPE_FIELD_TYPE (type, 0); - index_type = TYPE_TARGET_TYPE (range_type); - low_bound = TYPE_FIELD_BITPOS (range_type, 0); - high_bound = TYPE_FIELD_BITPOS (range_type, 1); - fputs_filtered ("ARRAY (", stream); - print_type_scalar (index_type, low_bound, stream); - fputs_filtered (":", stream); - print_type_scalar (index_type, high_bound, stream); - fputs_filtered (") ", stream); - chill_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level); - break; - - case TYPE_CODE_BITSTRING: - fprintf_filtered (stream, "BOOLS (%d)", - TYPE_FIELD_BITPOS (TYPE_FIELD_TYPE(type,0), 1) + 1); - break; - - case TYPE_CODE_SET: - fputs_filtered ("POWERSET ", stream); - chill_print_type (TYPE_FIELD_TYPE (type, 0), "", stream, - show - 1, level); - break; - - case TYPE_CODE_STRING: - range_type = TYPE_FIELD_TYPE (type, 0); - index_type = TYPE_TARGET_TYPE (range_type); - high_bound = TYPE_FIELD_BITPOS (range_type, 1); - fputs_filtered ("CHARS (", stream); - print_type_scalar (index_type, high_bound + 1, stream); - fputs_filtered (")", stream); - break; - - case TYPE_CODE_MEMBER: - fprintf_filtered (stream, "MEMBER "); - chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); - break; - case TYPE_CODE_REF: - fprintf_filtered (stream, "/*LOC*/ "); - chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); - break; - case TYPE_CODE_FUNC: - fprintf_filtered (stream, "PROC (?)"); - chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); - break; - - case TYPE_CODE_STRUCT: - if (chill_is_varying_struct (type)) - { - chill_type_print_base (TYPE_FIELD_TYPE (type, 1), - stream, show, level); - fputs_filtered (" VARYING", stream); - } - else - { - fprintf_filtered (stream, "STRUCT "); - - 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, "\n"); - } - else - { - fprintfi_filtered (level + 4, stream, "\n"); - } - } - else - { - len = TYPE_NFIELDS (type); - for (i = TYPE_N_BASECLASSES (type); i < len; i++) - { - struct type *field_type = TYPE_FIELD_TYPE (type, i); - QUIT; - print_spaces_filtered (level + 4, stream); - if (TYPE_CODE (field_type) == TYPE_CODE_UNION) - { int j; /* variant number */ - fputs_filtered ("CASE OF\n", stream); - for (j = 0; j < TYPE_NFIELDS (field_type); j++) - { int k; /* variant field index */ - struct type *variant_type - = TYPE_FIELD_TYPE (field_type, j); - int var_len = TYPE_NFIELDS (variant_type); - print_spaces_filtered (level + 4, stream); - if (strcmp (TYPE_FIELD_NAME (field_type, j), - "else") == 0) - fputs_filtered ("ELSE\n", stream); - else - fputs_filtered (":\n", stream); - if (TYPE_CODE (variant_type) != TYPE_CODE_STRUCT) - error ("variant record confusion"); - for (k = 0; k < var_len; k++) - { - print_spaces_filtered (level + 8, stream); - chill_print_type (TYPE_FIELD_TYPE (variant_type, k), - TYPE_FIELD_NAME (variant_type, k), - stream, show - 1, level + 8); - if (k < (var_len - 1)) - fputs_filtered (",", stream); - fputs_filtered ("\n", stream); - } - } - fputs_filtered ("ESAC\n", stream); - } - else - chill_print_type (field_type, - TYPE_FIELD_NAME (type, i), - stream, show - 1, level + 4); - if (i < (len - 1)) - { - fputs_filtered (",", stream); - } - fputs_filtered ("\n", stream); - } - } - fprintfi_filtered (level, stream, ")"); - } - break; - - case TYPE_CODE_RANGE: - if (TYPE_DUMMY_RANGE (type)) - chill_type_print_base (TYPE_TARGET_TYPE (type), - stream, show, level); - else if (TYPE_TARGET_TYPE (type)) - { - chill_type_print_base (TYPE_TARGET_TYPE (type), - stream, show, level); - fputs_filtered (" (", stream); - print_type_scalar (TYPE_TARGET_TYPE (type), - TYPE_FIELD_BITPOS (type, 0), stream); - fputs_filtered (":", stream); - print_type_scalar (TYPE_TARGET_TYPE (type), - TYPE_FIELD_BITPOS (type, 1), stream); - fputs_filtered (")", stream); - } - else - fprintf_filtered (stream, "RANGE? (%s : %d)", - TYPE_FIELD_BITPOS (type, 0), - TYPE_FIELD_BITPOS (type, 1)); - break; - - case TYPE_CODE_ENUM: - { - register int lastval = 0; - fprintf_filtered (stream, "SET ("); - len = TYPE_NFIELDS (type); - for (i = 0; i < len; i++) - { - QUIT; - if (i) fprintf_filtered (stream, ", "); - wrap_here (" "); - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - if (lastval != TYPE_FIELD_BITPOS (type, i)) - { - fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i)); - lastval = TYPE_FIELD_BITPOS (type, i); - } - lastval++; - } - fprintf_filtered (stream, ")"); - } - break; - - case TYPE_CODE_VOID: - case TYPE_CODE_UNDEF: - case TYPE_CODE_ERROR: - case TYPE_CODE_UNION: - case TYPE_CODE_METHOD: - error ("missing language support in chill_type_print_base"); - break; - - default: - - /* Handle types not explicitly handled by the other cases, - such as fundamental types. For these, just print whatever - the type name is, as recorded in the type itself. If there - is no type name, then complain. */ - - if (TYPE_NAME (type) != NULL) - { - fputs_filtered (TYPE_NAME (type), stream); - } - else - { - error ("Unrecognized type code (%d) in symbol table.", - TYPE_CODE (type)); - } - break; - } -} diff --git a/gnu/usr.bin/gdb/gdb/ch-valprint.c b/gnu/usr.bin/gdb/gdb/ch-valprint.c deleted file mode 100644 index 074329b..0000000 --- a/gnu/usr.bin/gdb/gdb/ch-valprint.c +++ /dev/null @@ -1,581 +0,0 @@ -/* Support for printing Chill values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include "obstack.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "valprint.h" -#include "expression.h" -#include "value.h" -#include "language.h" -#include "demangle.h" -#include "c-lang.h" /* For c_val_print */ -#include "typeprint.h" -#include "ch-lang.h" - -static void -chill_print_value_fields PARAMS ((struct type *, char *, GDB_FILE *, int, int, - enum val_prettyprint, struct type **)); - - -/* Print the elements of an array. - Similar to val_print_array_elements, but prints - element indexes (in Chill syntax). */ - -static void -chill_val_print_array_elements (type, valaddr, 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; -{ - unsigned int i = 0; - unsigned int things_printed = 0; - unsigned len; - struct type *elttype; - struct type *range_type = TYPE_FIELD_TYPE (type, 0); - struct type *index_type = TYPE_TARGET_TYPE (range_type); - unsigned eltlen; - /* Position of the array element we are examining to see - whether it is repeated. */ - unsigned int rep1; - /* Number of repetitions we have detected so far. */ - unsigned int reps; - LONGEST low_bound = TYPE_FIELD_BITPOS (range_type, 0); - LONGEST high_bound = TYPE_FIELD_BITPOS (range_type, 1); - - elttype = TYPE_TARGET_TYPE (type); - eltlen = TYPE_LENGTH (elttype); - len = TYPE_LENGTH (type) / eltlen; - - annotate_array_section_begin (i, elttype); - - for (; i < len && things_printed < print_max; i++) - { - if (i != 0) - { - if (prettyprint_arrays) - { - fprintf_filtered (stream, ",\n"); - print_spaces_filtered (2 + 2 * recurse, stream); - } - else - { - fprintf_filtered (stream, ", "); - } - } - wrap_here (n_spaces (2 + 2 * recurse)); - - rep1 = i + 1; - reps = 1; - while ((rep1 < len) && - !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen)) - { - ++reps; - ++rep1; - } - - fputs_filtered ("(", stream); - print_type_scalar (index_type, low_bound + i, stream); - if (reps > 1) - { - fputs_filtered (":", stream); - print_type_scalar (index_type, low_bound + i + reps - 1, stream); - fputs_filtered ("): ", stream); - val_print (elttype, valaddr + i * eltlen, 0, stream, format, - deref_ref, recurse + 1, pretty); - - i = rep1 - 1; - things_printed += 1; - } - else - { - fputs_filtered ("): ", stream); - val_print (elttype, valaddr + i * eltlen, 0, stream, format, - deref_ref, recurse + 1, pretty); - annotate_elt (); - things_printed++; - } - } - annotate_array_section_end (); - if (i < len) - { - 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 -chill_val_print (type, valaddr, 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; -{ - LONGEST val; - unsigned int i = 0; /* Number of characters printed. */ - struct type *elttype; - CORE_ADDR addr; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: - if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) - { - if (prettyprint_arrays) - { - print_spaces_filtered (2 + 2 * recurse, stream); - } - fprintf_filtered (stream, "["); - chill_val_print_array_elements (type, valaddr, address, stream, - format, deref_ref, recurse, pretty); - fprintf_filtered (stream, "]"); - } - else - { - error ("unimplemented in chill_val_print; unspecified array length"); - } - break; - - case TYPE_CODE_INT: - 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_CHAR: - format = format ? format : output_format; - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - } - else - { - LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr), - stream); - } - break; - - case TYPE_CODE_FLT: - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - } - else - { - print_floating (valaddr, type, stream); - } - break; - - case TYPE_CODE_BOOL: - format = format ? format : output_format; - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - } - else - { - /* FIXME: Why is this using builtin_type_chill_bool not type? */ - val = unpack_long (builtin_type_chill_bool, valaddr); - fprintf_filtered (stream, val ? "TRUE" : "FALSE"); - } - break; - - case TYPE_CODE_UNDEF: - /* This happens (without TYPE_FLAG_STUB set) on systems which don't use - dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" - and no complete type for struct foo in that file. */ - fprintf_filtered (stream, ""); - break; - - case TYPE_CODE_PTR: - if (format && format != 's') - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } - addr = unpack_pointer (type, valaddr); - elttype = TYPE_TARGET_TYPE (type); - - /* We assume a NULL pointer is all zeros ... */ - if (addr == 0) - { - fputs_filtered ("NULL", stream); - return 0; - } - - if (TYPE_CODE (elttype) == 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') - { - print_address_numeric (addr, 1, stream); - } - - /* For a pointer to char or unsigned char, also print the string - pointed to, unless pointer is null. */ - if (TYPE_LENGTH (elttype) == 1 - && TYPE_CODE (elttype) == TYPE_CODE_CHAR - && (format == 0 || format == 's') - && addr != 0 - && /* 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); - } - /* Return number of characters printed, plus one for the - terminating null if we have "reached the end". */ - return (i + (print_max && i != print_max)); - break; - - case TYPE_CODE_STRING: - if (format && format != 's') - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } - i = TYPE_LENGTH (type); - LA_PRINT_STRING (stream, valaddr, i, 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)); - break; - - case TYPE_CODE_BITSTRING: - case TYPE_CODE_SET: - elttype = TYPE_FIELD_TYPE (type, 0); - check_stub_type (elttype); - if (TYPE_FLAGS (elttype) & TYPE_FLAG_STUB) - { - fprintf_filtered (stream, ""); - gdb_flush (stream); - break; - } - { - struct type *range = elttype; - int low_bound = TYPE_LOW_BOUND (range); - int high_bound = TYPE_HIGH_BOUND (range); - int i; - int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING; - int need_comma = 0; - - if (is_bitstring) - fputs_filtered ("B'", stream); - else - fputs_filtered ("[", stream); - for (i = low_bound; i <= high_bound; i++) - { - int element = value_bit_index (type, valaddr, i); - if (is_bitstring) - fprintf_filtered (stream, "%d", element); - else if (element) - { - if (need_comma) - fputs_filtered (", ", stream); - print_type_scalar (TYPE_TARGET_TYPE (range), i, stream); - need_comma = 1; - - /* Look for a continuous range of true elements. */ - if (i+1 <= high_bound && value_bit_index (type, valaddr, ++i)) - { - int j = i; /* j is the upper bound so far of the range */ - fputs_filtered (":", stream); - while (i+1 <= high_bound - && value_bit_index (type, valaddr, ++i)) - j = i; - print_type_scalar (TYPE_TARGET_TYPE (range), j, stream); - } - } - } - if (is_bitstring) - fputs_filtered ("'", stream); - else - fputs_filtered ("]", stream); - } - break; - - case TYPE_CODE_STRUCT: - if (chill_is_varying_struct (type)) - { - struct type *inner = TYPE_FIELD_TYPE (type, 1); - long length = unpack_long (TYPE_FIELD_TYPE (type, 0), valaddr); - char *data_addr = valaddr + TYPE_FIELD_BITPOS (type, 1) / 8; - - switch (TYPE_CODE (inner)) - { - case TYPE_CODE_STRING: - if (length > TYPE_LENGTH (type)) - { - fprintf_filtered (stream, - " static length %d>", - length, TYPE_LENGTH (type)); - } - LA_PRINT_STRING (stream, data_addr, length, 0); - return length; - default: - break; - } - } - chill_print_value_fields (type, valaddr, stream, format, recurse, pretty, - 0); - break; - - case TYPE_CODE_REF: - if (addressprint) - { - fprintf_filtered (stream, "LOC("); - print_address_numeric - (extract_address (valaddr, TARGET_PTR_BIT / HOST_CHAR_BIT), - 1, - stream); - fprintf_filtered (stream, ")"); - if (deref_ref) - fputs_filtered (": ", stream); - } - /* De-reference the reference. */ - if (deref_ref) - { - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF) - { - value_ptr deref_val = - value_at - (TYPE_TARGET_TYPE (type), - unpack_pointer (lookup_pointer_type (builtin_type_void), - valaddr)); - val_print (VALUE_TYPE (deref_val), - VALUE_CONTENTS (deref_val), - VALUE_ADDRESS (deref_val), stream, format, - deref_ref, recurse + 1, pretty); - } - else - fputs_filtered ("???", stream); - } - break; - - case TYPE_CODE_ENUM: - c_val_print (type, valaddr, 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, - format, deref_ref, recurse, pretty); - break; - - case TYPE_CODE_MEMBER: - case TYPE_CODE_UNION: - case TYPE_CODE_FUNC: - case TYPE_CODE_VOID: - case TYPE_CODE_ERROR: - default: - /* Let's defer printing to the C printer, rather than - print an error message. FIXME! */ - c_val_print (type, valaddr, address, stream, format, - deref_ref, recurse, pretty); - } - gdb_flush (stream); - return (0); -} - -/* Mutually recursive subroutines of cplus_print_value and c_val_print to - print out a structure's fields: cp_print_value_fields and cplus_print_value. - - TYPE, VALADDR, STREAM, RECURSE, and PRETTY have the - same meanings as in cplus_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. */ - -static void -chill_print_value_fields (type, valaddr, stream, format, recurse, pretty, - dont_print) - struct type *type; - char *valaddr; - GDB_FILE *stream; - int format; - int recurse; - enum val_prettyprint pretty; - struct type **dont_print; -{ - int i, len; - int fields_seen = 0; - - check_stub_type (type); - - fprintf_filtered (stream, "["); - len = TYPE_NFIELDS (type); - if (len == 0) - { - fprintf_filtered (stream, ""); - } - else - { - for (i = 0; i < len; i++) - { - if (fields_seen) - { - fprintf_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)); - } - fputs_filtered (".", stream); - fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), - language_chill, DMGL_NO_OPTS); - fputs_filtered (": ", stream); - if (TYPE_FIELD_PACKED (type, i)) - { - value_ptr v; - - /* Bitfields require special handling, especially due to byte - order problems. */ - 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, - stream, format, 0, recurse + 1, pretty); - } - else - { - chill_val_print (TYPE_FIELD_TYPE (type, i), - valaddr + TYPE_FIELD_BITPOS (type, i) / 8, - 0, stream, format, 0, recurse + 1, pretty); - } - } - if (pretty) - { - fprintf_filtered (stream, "\n"); - print_spaces_filtered (2 * recurse, stream); - } - } - fprintf_filtered (stream, "]"); -} - -int -chill_value_print (val, stream, format, pretty) - value_ptr val; - GDB_FILE *stream; - int format; - enum val_prettyprint pretty; -{ - /* A "repeated" value really contains several values in a row. - They are made by the @ operator. - Print such values as if they were arrays. */ - - if (VALUE_REPEATED (val)) - { - register unsigned int n = VALUE_REPETITIONS (val); - register unsigned int typelen = TYPE_LENGTH (VALUE_TYPE (val)); - fprintf_filtered (stream, "["); - /* Print arrays of characters using string syntax. */ - if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT - && format == 0) - LA_PRINT_STRING (stream, VALUE_CONTENTS (val), n, 0); - else - { - value_print_array_elements (val, stream, format, pretty); - } - fprintf_filtered (stream, "]"); - return (n * typelen); - } - else - { - struct type *type = VALUE_TYPE (val); - - /* If it is a pointer, indicate what it points to. - - Print type also if it is a reference. - - C++: if it is a member pointer, we will take care - of that when we print it. */ - if (TYPE_CODE (type) == TYPE_CODE_PTR || - TYPE_CODE (type) == TYPE_CODE_REF) - { - char *valaddr = VALUE_CONTENTS (val); - CORE_ADDR addr = unpack_pointer (type, valaddr); - if (TYPE_CODE (type) != TYPE_CODE_PTR || addr != 0) - { - int i; - char *name = TYPE_NAME (type); - if (name) - fputs_filtered (name, stream); - else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID) - fputs_filtered ("PTR", stream); - else - { - fprintf_filtered (stream, "("); - type_print (type, "", stream, -1); - fprintf_filtered (stream, ")"); - } - fprintf_filtered (stream, "("); - i = val_print (type, valaddr, VALUE_ADDRESS (val), - stream, format, 1, 0, pretty); - fprintf_filtered (stream, ")"); - return i; - } - } - return (val_print (type, VALUE_CONTENTS (val), - VALUE_ADDRESS (val), stream, format, 1, 0, pretty)); - } -} - - diff --git a/gnu/usr.bin/gdb/gdb/coffread.c b/gnu/usr.bin/gdb/gdb/coffread.c deleted file mode 100644 index b0830c9..0000000 --- a/gnu/usr.bin/gdb/gdb/coffread.c +++ /dev/null @@ -1,2101 +0,0 @@ -/* Read coff symbol tables and convert to internal format, for GDB. - Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu). - Copyright 1987, 1988, 1989, 1990, 1991, 1992, 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. */ - -#include "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "breakpoint.h" - -#include "bfd.h" -#include - -#include - -#include /* For time_t in libbfd.h. */ -#include /* For time_t, if not in time.h. */ -#include "libbfd.h" /* FIXME secret internal data from BFD */ -#include "coff/internal.h" /* Internal format of COFF symbols in BFD */ -#include "libcoff.h" /* FIXME secret internal data from BFD */ - -#include "symfile.h" -#include "objfiles.h" -#include "buildsym.h" -#include "gdb-stabs.h" -#include "stabsread.h" -#include "complaints.h" - -struct coff_symfile_info { - file_ptr min_lineno_offset; /* Where in file lowest line#s are */ - file_ptr max_lineno_offset; /* 1+last byte of line#s in file */ - - asection *stabsect; /* Section pointer for .stab section */ - asection *stabstrsect; /* Section pointer for .stab section */ - asection *stabindexsect; /* Section pointer for .stab.index section */ - char *stabstrdata; -}; - -/* Translate an external name string into a user-visible name. */ -#define EXTERNAL_NAME(string, abfd) \ - (string[0] == bfd_get_symbol_leading_char(abfd)? string+1: string) - -/* To be an sdb debug type, type must have at least a basic or primary - derived type. Using this rather than checking against T_NULL is - said to prevent core dumps if we try to operate on Michael Bloom - dbx-in-coff file. */ - -#define SDB_TYPE(type) (BTYPE(type) | (type & N_TMASK)) - -/* - * Convert from an sdb register number to an internal gdb register number. - * This should be defined in tm.h, if REGISTER_NAMES is not set up - * to map one to one onto the sdb register numbers. - */ -#ifndef SDB_REG_TO_REGNUM -# define SDB_REG_TO_REGNUM(value) (value) -#endif - -/* Core address of start and end of text of current source file. - This comes from a ".text" symbol where x_nlinno > 0. */ - -static CORE_ADDR cur_src_start_addr; -static CORE_ADDR cur_src_end_addr; - -/* The addresses of the symbol table stream and number of symbols - of the object file we are reading (as copied into core). */ - -static GDB_FILE *nlist_stream_global; -static int nlist_nsyms_global; - -/* Vector of line number information. */ - -static struct linetable *line_vector; - -/* Index of next entry to go in line_vector_index. */ - -static int line_vector_index; - -/* Last line number recorded in the line vector. */ - -static int prev_line_number; - -/* Number of elements allocated for line_vector currently. */ - -static int line_vector_length; - -/* Pointers to scratch storage, used for reading raw symbols and auxents. */ - -static char *temp_sym; -static char *temp_aux; - -/* Local variables that hold the shift and mask values for the - COFF file that we are currently reading. These come back to us - from BFD, and are referenced by their macro names, as well as - internally to the BTYPE, ISPTR, ISFCN, ISARY, ISTAG, and DECREF - macros from ../internalcoff.h . */ - -static unsigned local_n_btmask; -static unsigned local_n_btshft; -static unsigned local_n_tmask; -static unsigned local_n_tshift; - -#define N_BTMASK local_n_btmask -#define N_BTSHFT local_n_btshft -#define N_TMASK local_n_tmask -#define N_TSHIFT local_n_tshift - -/* Local variables that hold the sizes in the file of various COFF structures. - (We only need to know this to read them from the file -- BFD will then - translate the data in them, into `internal_xxx' structs in the right - byte order, alignment, etc.) */ - -static unsigned local_linesz; -static unsigned local_symesz; -static unsigned local_auxesz; - - -/* Chain of typedefs of pointers to empty struct/union types. - They are chained thru the SYMBOL_VALUE_CHAIN. */ - -static struct symbol *opaque_type_chain[HASHSIZE]; - -#if 0 -/* The type of the function we are currently reading in. This is - used by define_symbol to record the type of arguments to a function. */ - -struct type *in_function_type; -#endif - -/* Complaints about various problems in the file being read */ - -struct complaint ef_complaint = - {"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0}; - -struct complaint bf_no_aux_complaint = - {"`.bf' symbol %d has no aux entry", 0, 0}; - -struct complaint ef_no_aux_complaint = - {"`.ef' symbol %d has no aux entry", 0, 0}; - -struct complaint lineno_complaint = - {"Line number pointer %d lower than start of line numbers", 0, 0}; - -struct complaint unexpected_type_complaint = - {"Unexpected type for symbol %s", 0, 0}; - -struct complaint bad_sclass_complaint = - {"Bad n_sclass for symbol %s", 0, 0}; - -struct complaint misordered_blocks_complaint = - {"Blocks out of order at address %x", 0, 0}; - -struct complaint tagndx_bad_complaint = - {"Symbol table entry for %s has bad tagndx value", 0, 0}; - -struct complaint eb_complaint = - {"Mismatched .eb symbol ignored starting at symnum %d", 0, 0}; - -/* Simplified internal version of coff symbol table information */ - -struct coff_symbol { - char *c_name; - int c_symnum; /* symbol number of this entry */ - int c_naux; /* 0 if syment only, 1 if syment + auxent, etc */ - long c_value; - int c_sclass; - int c_secnum; - unsigned int c_type; -}; - -static struct type * -coff_read_struct_type PARAMS ((int, int, int)); - -static struct type * -decode_base_type PARAMS ((struct coff_symbol *, unsigned int, - union internal_auxent *)); - -static struct type * -decode_type PARAMS ((struct coff_symbol *, unsigned int, - union internal_auxent *)); - -static struct type * -decode_function_type PARAMS ((struct coff_symbol *, unsigned int, - union internal_auxent *)); - -static struct type * -coff_read_enum_type PARAMS ((int, int, int)); - -static struct symbol * -process_coff_symbol PARAMS ((struct coff_symbol *, union internal_auxent *, - struct objfile *)); - -static void -patch_opaque_types PARAMS ((struct symtab *)); - -static void -patch_type PARAMS ((struct type *, struct type *)); - -static void -enter_linenos PARAMS ((long, int, int)); - -static void -free_linetab PARAMS ((void)); - -static int -init_lineno PARAMS ((int, long, int)); - -static char * -getsymname PARAMS ((struct internal_syment *)); - -static void -free_stringtab PARAMS ((void)); - -static int -init_stringtab PARAMS ((int, long)); - -static void -read_one_sym PARAMS ((struct coff_symbol *, struct internal_syment *, - union internal_auxent *)); - -static void -read_coff_symtab PARAMS ((long, int, struct objfile *)); - -static void -find_linenos PARAMS ((bfd *, sec_ptr, PTR)); - -static void -coff_symfile_init PARAMS ((struct objfile *)); - -static void -coff_new_init PARAMS ((struct objfile *)); - -static void -coff_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int)); - -static void -coff_symfile_finish PARAMS ((struct objfile *)); - -static void record_minimal_symbol - PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type, struct objfile *)); - -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_record_line PARAMS ((int, CORE_ADDR)); - -static struct type * -coff_alloc_type PARAMS ((int)); - -static struct type ** -coff_lookup_type PARAMS ((int)); - - -static void -coff_locate_sections PARAMS ((bfd *, asection *, PTR)); - -/* We are called once per section from coff_symfile_read. We - need to examine each section we are passed, check to see - if it is something we are interested in processing, and - if so, stash away some access information for the section. - - FIXME: The section names should not be hardwired strings (what - should they be? I don't think most object file formats have enough - section flags to specify what kind of debug section it is - -kingdon). */ - -static void -coff_locate_sections (ignore_abfd, sectp, csip) - bfd *ignore_abfd; - asection *sectp; - PTR csip; -{ - register struct coff_symfile_info *csi; - - csi = (struct coff_symfile_info *) csip; - if (STREQ (sectp->name, ".stab")) - { - csi->stabsect = sectp; - } - else if (STREQ (sectp->name, ".stabstr")) - { - csi->stabstrsect = sectp; - } - else if (STREQ (sectp->name, ".stab.index")) - { - csi->stabindexsect = sectp; - } -} - -/* 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. - - This can be used for finding the type associated with that index - or for associating a new type with the index. */ - -static struct type ** -coff_lookup_type (index) - register int index; -{ - if (index >= type_vector_length) - { - int old_vector_length = type_vector_length; - - type_vector_length *= 2; - if (index /* is still */ >= type_vector_length) { - type_vector_length = index * 2; - } - type_vector = (struct type **) - xrealloc ((char *) type_vector, - type_vector_length * sizeof (struct type *)); - memset (&type_vector[old_vector_length], 0, - (type_vector_length - old_vector_length) * sizeof(struct type *)); - } - return &type_vector[index]; -} - -/* Make sure there is a type allocated for type number index - and return the type object. - This can create an empty (zeroed) type object. */ - -static struct type * -coff_alloc_type (index) - int index; -{ - register struct type **type_addr = coff_lookup_type (index); - register struct type *type = *type_addr; - - /* If we are referring to a type not known at all yet, - allocate an empty type for it. - We will fill it in later if we find out how. */ - if (type == NULL) - { - type = alloc_type (current_objfile); - *type_addr = type; - } - return type; -} - -/* Record a line number entry for line LINE at address PC. - FIXME: Use record_line instead. */ - -static void -coff_record_line (line, pc) - int line; - CORE_ADDR pc; -{ - struct linetable_entry *e; - /* Make sure line vector is big enough. */ - - if (line_vector_index + 2 >= line_vector_length) - { - line_vector_length *= 2; - line_vector = (struct linetable *) - xrealloc ((char *) line_vector, sizeof (struct linetable) - + (line_vector_length - * sizeof (struct linetable_entry))); - } - - e = line_vector->item + line_vector_index++; - e->line = line; e->pc = pc; -} - -/* Start a new symtab for a new source file. - This is called when a COFF ".file" symbol is seen; - it indicates the start of data for one original source file. */ - -static void -coff_start_symtab () -{ - start_symtab ( - /* We fill in the filename later. start_symtab - puts this pointer into last_source file and in - coff_end_symtab we assume we can free() it. - FIXME: leaks memory. */ - savestring ("", 0), - /* 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); - - /* Initialize the source file line number information for this file. */ - - if (line_vector) /* Unlikely, but maybe possible? */ - free ((PTR)line_vector); - line_vector_index = 0; - line_vector_length = 1000; - prev_line_number = -2; /* Force first line number to be explicit */ - line_vector = (struct linetable *) - xmalloc (sizeof (struct linetable) - + line_vector_length * sizeof (struct linetable_entry)); -} - -/* Save the vital information from when starting to read a file, - for use when closing off the current file. - NAME is the file name the symbols came from, START_ADDR is the first - text address for the file, and SIZE is the number of bytes of text. */ - -static void -complete_symtab (name, start_addr, size) - char *name; - CORE_ADDR start_addr; - unsigned int size; -{ - last_source_file = savestring (name, strlen (name)); - cur_src_start_addr = start_addr; - cur_src_end_addr = start_addr + size; - - if (current_objfile -> ei.entry_point >= cur_src_start_addr && - current_objfile -> ei.entry_point < cur_src_end_addr) - { - current_objfile -> ei.entry_file_lowpc = cur_src_start_addr; - current_objfile -> ei.entry_file_highpc = cur_src_end_addr; - } -} - -/* 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. */ - -static void -coff_end_symtab (objfile) - struct objfile *objfile; -{ - struct symtab *symtab; - - last_source_start_addr = cur_src_start_addr; - - /* For no good reason, this file stores the number of entries in a - separate variable instead of in line_vector->nitems. Fix it. */ - if (line_vector) - line_vector->nitems = line_vector_index; - - /* For COFF, we only have one subfile, so we can just look at - subfiles and not worry about there being other elements in the - chain. We fill in various fields now because we didn't know them - 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; - - /* sort_pending is needed for amdcoff, at least. - sort_linevec is needed for the SCO compiler. */ - symtab = end_symtab (cur_src_end_addr, 1, 1, objfile, 0); - - if (symtab != NULL) - free_named_symtabs (symtab->filename); - - /* Reinitialize for beginning of new file. */ - line_vector = 0; - line_vector_length = -1; - last_source_file = NULL; -} - -static void -record_minimal_symbol (name, address, type, objfile) - char *name; - CORE_ADDR address; - enum minimal_symbol_type type; - struct objfile *objfile; -{ - /* We don't want TDESC entry points in the minimal symbol table */ - if (name[0] == '@') return; - - prim_record_minimal_symbol (savestring (name, strlen (name)), address, type, - objfile); -} - -/* coff_symfile_init () - is the coff-specific initialization routine for reading symbols. - It is passed a struct objfile which contains, among other things, - the BFD for the file whose symbols are being read, and a slot for - a pointer to "private data" which we fill with cookies and other - treats for coff_symfile_read (). - - We will only be called if this is a COFF or COFF-like file. - BFD handles figuring out the format of the file, and code in symtab.c - uses BFD's determination to vector to us. - - The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */ - -static int text_bfd_scnum; - -static void -coff_symfile_init (objfile) - struct objfile *objfile; -{ - asection *section; - bfd *abfd = objfile->obfd; - - /* Allocate struct to keep track of stab reading. */ - objfile->sym_stab_info = (PTR) - xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info)); - - memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info)); - - /* Allocate struct to keep track of the symfile */ - objfile -> sym_private = xmmalloc (objfile -> md, - sizeof (struct coff_symfile_info)); - - memset (objfile->sym_private, 0, sizeof (struct coff_symfile_info)); - - init_entry_point_info (objfile); - - /* Save the section number for the text section */ - section = bfd_get_section_by_name (abfd, ".text"); - if (section) - text_bfd_scnum = section->index; - else - text_bfd_scnum = -1; -} - -/* This function is called for every section; it finds the outer limits - of the line table (minimum and maximum file offset) so that the - mainline code can read the whole thing for efficiency. */ - -/* ARGSUSED */ -static void -find_linenos (abfd, asect, vpinfo) - bfd *abfd; - sec_ptr asect; - PTR vpinfo; -{ - struct coff_symfile_info *info; - int size, count; - file_ptr offset, maxoff; - -/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ - count = asect->lineno_count; -/* End of warning */ - - if (count == 0) - return; - size = count * local_linesz; - - info = (struct coff_symfile_info *)vpinfo; -/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ - offset = asect->line_filepos; -/* End of warning */ - - if (offset < info->min_lineno_offset || info->min_lineno_offset == 0) - info->min_lineno_offset = offset; - - maxoff = offset + size; - if (maxoff > info->max_lineno_offset) - info->max_lineno_offset = maxoff; -} - - -/* The BFD for this file -- only good while we're actively reading - symbols into a psymtab or a symtab. */ - -static bfd *symfile_bfd; - -/* Read a symbol file, after initialization by coff_symfile_init. */ -/* FIXME! Addr and Mainline are not used yet -- this will not work for - shared libraries or add_file! */ - -/* ARGSUSED */ -static void -coff_symfile_read (objfile, section_offsets, mainline) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; -{ - struct coff_symfile_info *info; - struct dbx_symfile_info *dbxinfo; - bfd *abfd = objfile->obfd; - coff_data_type *cdata = coff_data (abfd); - char *name = bfd_get_filename (abfd); - int desc; - register int val; - int num_symbols; - int symtab_offset; - int stringtab_offset; - struct cleanup *back_to; - int stabsize, stabstrsize; - - info = (struct coff_symfile_info *) objfile -> sym_private; - dbxinfo = (struct dbx_symfile_info *) objfile->sym_stab_info; - symfile_bfd = abfd; /* Kludge for swap routines */ - -/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ - desc = fileno ((GDB_FILE *)(abfd->iostream)); /* File descriptor */ - num_symbols = bfd_get_symcount (abfd); /* How many syms */ - symtab_offset = cdata->sym_filepos; /* Symbol table file offset */ - stringtab_offset = symtab_offset + /* String table file offset */ - num_symbols * cdata->local_symesz; - - /* Set a few file-statics that give us specific information about - the particular COFF file format we're reading. */ - local_linesz = cdata->local_linesz; - local_n_btmask = cdata->local_n_btmask; - local_n_btshft = cdata->local_n_btshft; - local_n_tmask = cdata->local_n_tmask; - local_n_tshift = cdata->local_n_tshift; - local_linesz = cdata->local_linesz; - local_symesz = cdata->local_symesz; - local_auxesz = cdata->local_auxesz; - - /* Allocate space for raw symbol and aux entries, based on their - space requirements as reported by BFD. */ - 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); -/* End of warning */ - - /* Read the line number table, all at once. */ - info->min_lineno_offset = 0; - info->max_lineno_offset = 0; - bfd_map_over_sections (abfd, find_linenos, (PTR) info); - - make_cleanup (free_linetab, 0); - val = init_lineno (desc, info->min_lineno_offset, - info->max_lineno_offset - info->min_lineno_offset); - if (val < 0) - error ("\"%s\": error reading line numbers\n", name); - - /* Now read the string table, all at once. */ - - make_cleanup (free_stringtab, 0); - val = init_stringtab (desc, stringtab_offset); - if (val < 0) - error ("\"%s\": can't get string table", name); - - init_minimal_symbol_collection (); - make_cleanup (discard_minimal_symbols, 0); - - /* Now that the executable file is positioned at symbol table, - process it and define symbols accordingly. */ - - read_coff_symtab ((long)symtab_offset, num_symbols, objfile); - - /* Sort symbols alphabetically within each block. */ - - { - struct symtab *s; - for (s = objfile -> symtabs; s != NULL; s = s -> next) - { - sort_symtab_syms (s); - } - } - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); - - bfd_map_over_sections (abfd, coff_locate_sections, (PTR) info); - - if (info->stabsect) - { - /* FIXME: dubious. Why can't we use something normal like - bfd_get_section_contents? */ - fseek ((GDB_FILE *) abfd->iostream, abfd->where, 0); - - stabsize = bfd_section_size (abfd, info->stabsect); - stabstrsize = bfd_section_size (abfd, info->stabstrsect); - - coffstab_build_psymtabs (objfile, - section_offsets, - mainline, - info->stabsect->filepos, stabsize, - info->stabstrsect->filepos, stabstrsize); - } - - do_cleanups (back_to); -} - -static void -coff_new_init (ignore) - struct objfile *ignore; -{ -} - -/* 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. */ - -static void -coff_symfile_finish (objfile) - struct objfile *objfile; -{ - if (objfile -> sym_private != NULL) - { - mfree (objfile -> md, objfile -> sym_private); - } -} - - -/* Given pointers to a symbol table in coff style exec file, - analyze them and create struct symtab's describing the symbols. - NSYMS is the number of symbols in the symbol table. - We read them one at a time using read_one_sym (). */ - -static void -read_coff_symtab (symtab_offset, nsyms, objfile) - long symtab_offset; - int nsyms; - struct objfile *objfile; -{ - GDB_FILE *stream; - register struct context_stack *new; - struct coff_symbol coff_symbol; - register struct coff_symbol *cs = &coff_symbol; - static struct internal_syment main_sym; - static union internal_auxent main_aux; - struct coff_symbol fcn_cs_saved; - static struct internal_syment fcn_sym_saved; - static union internal_auxent fcn_aux_saved; - struct symtab *s; - - /* A .file is open. */ - int in_source_file = 0; - int next_file_symnum = -1; - - /* Name of the current file. */ - char *filestring = ""; - int depth = 0; - int fcn_first_line = 0; - int fcn_last_line = 0; - int fcn_start_addr = 0; - long fcn_line_ptr = 0; - int val; - - stream = bfd_cache_lookup(objfile->obfd); - if (!stream) - perror_with_name(objfile->name); - - /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous.... - it's hard to know I've really worked around it. The fix should be - harmless, anyway). The symptom of the bug is that the first - fread (in read_one_sym), will (in my example) actually get data - from file offset 268, when the fseek was to 264 (and ftell shows - 264). This causes all hell to break loose. I was unable to - reproduce this on a short test program which operated on the same - file, performing (I think) the same sequence of operations. - - It stopped happening when I put in this rewind(). - - FIXME: Find out if this has been reported to Sun, whether it has - been fixed in a later release, etc. */ - - rewind (stream); - - /* Position to read the symbol table. */ - val = fseek (stream, (long)symtab_offset, 0); - if (val < 0) - perror_with_name (objfile->name); - - current_objfile = objfile; - nlist_stream_global = stream; - nlist_nsyms_global = nsyms; - last_source_file = NULL; - memset (opaque_type_chain, 0, sizeof opaque_type_chain); - - if (type_vector) /* Get rid of previous one */ - free ((PTR)type_vector); - type_vector_length = 160; - type_vector = (struct type **) - xmalloc (type_vector_length * sizeof (struct type *)); - memset (type_vector, 0, type_vector_length * sizeof (struct type *)); - - coff_start_symtab (); - - symnum = 0; - while (symnum < nsyms) - { - QUIT; /* Make this command interruptable. */ - 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 (); - complete_symtab ("_globals_", 0, 0); - /* done with all files, everything from here on out is globals */ - } - - /* Special case for file with type declarations only, no text. */ - if (!last_source_file && SDB_TYPE (cs->c_type) - && cs->c_secnum == N_DEBUG) - complete_symtab (filestring, 0, 0); - - /* Typedefs should not be treated as symbol definitions. */ - if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF) - { - /* Record all functions -- external and static -- in minsyms. */ - record_minimal_symbol (cs->c_name, cs->c_value, mst_text, objfile); - - fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr; - fcn_start_addr = cs->c_value; - fcn_cs_saved = *cs; - fcn_sym_saved = main_sym; - fcn_aux_saved = main_aux; - continue; - } - - switch (cs->c_sclass) - { - case C_EFCN: - case C_EXTDEF: - case C_ULABEL: - case C_USTATIC: - case C_LINE: - case C_ALIAS: - case C_HIDDEN: - complain (&bad_sclass_complaint, cs->c_name); - break; - - case C_FILE: - /* - * c_value field contains symnum of next .file entry in table - * or symnum of first global after last .file. - */ - next_file_symnum = cs->c_value; - if (cs->c_naux > 0) - filestring = coff_getfilename (&main_aux); - else - filestring = ""; - - /* - * Complete symbol table for last object file - * containing debugging information. - */ - if (last_source_file) - { - coff_end_symtab (objfile); - coff_start_symtab (); - } - in_source_file = 1; - break; - - case C_STAT: - if (cs->c_name[0] == '.') { - if (STREQ (cs->c_name, ".text")) { - /* FIXME: don't wire in ".text" as section name - or symbol name! */ - /* Check for in_source_file deals with case of - a file with debugging symbols - followed by a later file with no symbols. */ - if (in_source_file) - complete_symtab (filestring, cs->c_value, - main_aux.x_scn.x_scnlen); - in_source_file = 0; - } - /* flush rest of '.' symbols */ - break; - } - else if (!SDB_TYPE (cs->c_type) - && cs->c_name[0] == 'L' - && (strncmp (cs->c_name, "LI%", 3) == 0 - || strncmp (cs->c_name, "LF%", 3) == 0 - || strncmp (cs->c_name,"LC%",3) == 0 - || strncmp (cs->c_name,"LP%",3) == 0 - || strncmp (cs->c_name,"LPB%",4) == 0 - || strncmp (cs->c_name,"LBB%",4) == 0 - || strncmp (cs->c_name,"LBE%",4) == 0 - || strncmp (cs->c_name,"LPBX%",5) == 0)) - /* At least on a 3b1, gcc generates swbeg and string labels - that look like this. Ignore them. */ - break; - /* fall in for static symbols that don't start with '.' */ - case C_EXT: - /* Record it in the minimal symbols regardless of SDB_TYPE. - This parallels what we do for other debug formats, and - probably is needed to make print_address_symbolic work right - without the "set fast-symbolic-addr off" kludge. */ - - /* FIXME: This bogusly assumes the sections are in a certain - order, text (SEC_CODE) sections are before data sections, - etc. */ - if (cs->c_secnum <= text_bfd_scnum+1) - { - /* text or absolute. (FIXME, should use mst_abs if - absolute). */ - record_minimal_symbol - (cs->c_name, cs->c_value, - cs->c_sclass == C_STAT ? mst_file_text : mst_text, - objfile); - } - else - { - record_minimal_symbol - (cs->c_name, cs->c_value, - cs->c_sclass == C_STAT ? mst_file_data : mst_data, - objfile); - } - if (SDB_TYPE (cs->c_type)) - process_coff_symbol (cs, &main_aux, objfile); - break; - - case C_FCN: - if (STREQ (cs->c_name, ".bf")) - { - within_function = 1; - - /* value contains address of first non-init type code */ - /* main_aux.x_sym.x_misc.x_lnsz.x_lnno - contains line number of '{' } */ - if (cs->c_naux != 1) - complain (&bf_no_aux_complaint, cs->c_symnum); - fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; - - /* Might want to check that locals are 0 and - context_stack_depth is zero, and complain if not. */ - - depth = 0; - new = push_context (depth, fcn_start_addr); - fcn_cs_saved.c_name = getsymname (&fcn_sym_saved); - new->name = process_coff_symbol (&fcn_cs_saved, - &fcn_aux_saved, objfile); - } - else if (STREQ (cs->c_name, ".ef")) - { - /* the value of .ef is the address of epilogue code; - not useful for gdb. */ - /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno - contains number of lines to '}' */ - new = pop_context (); - /* Stack must be empty now. */ - if (context_stack_depth > 0 || new == NULL) - { - complain (&ef_complaint, cs->c_symnum); - within_function = 0; - break; - } - if (cs->c_naux != 1) - { - complain (&ef_no_aux_complaint, cs->c_symnum); - fcn_last_line = 0x7FFFFFFF; - } - else - { - fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; - } - enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line); - - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, -#if defined (FUNCTION_EPILOGUE_SIZE) - /* This macro should be defined only on - machines where the - fcn_aux_saved.x_sym.x_misc.x_fsize - field is always zero. - So use the .bf record information that - points to the epilogue and add the size - of the epilogue. */ - cs->c_value + FUNCTION_EPILOGUE_SIZE, -#else - fcn_cs_saved.c_value + - fcn_aux_saved.x_sym.x_misc.x_fsize, -#endif - objfile - ); - within_function = 0; - } - break; - - case C_BLOCK: - if (STREQ (cs->c_name, ".bb")) - { - push_context (++depth, cs->c_value); - } - else if (STREQ (cs->c_name, ".eb")) - { - new = pop_context (); - if (depth-- != new->depth) - { - complain (&eb_complaint, symnum); - break; - } - if (local_symbols && context_stack_depth > 0) - { - /* Make a block for the local symbols within. */ - finish_block (0, &local_symbols, new->old_blocks, - new->start_addr, cs->c_value, objfile); - } - /* Now pop locals of block just finished. */ - local_symbols = new->locals; - } - break; - - default: - process_coff_symbol (cs, &main_aux, objfile); - break; - } - } - - if (last_source_file) - coff_end_symtab (objfile); - - /* Patch up any opaque types (references to types that are not defined - in the file where they are referenced, e.g. "struct foo *bar"). */ - ALL_OBJFILE_SYMTABS (objfile, s) - patch_opaque_types (s); - - current_objfile = NULL; -} - -/* Routines for reading headers and symbols from executable. */ - -#ifdef FIXME -/* Move these XXXMAGIC symbol defns into BFD! */ - -/* Read COFF file header, check magic number, - and return number of symbols. */ -read_file_hdr (chan, file_hdr) - int chan; - FILHDR *file_hdr; -{ - lseek (chan, 0L, 0); - if (myread (chan, (char *)file_hdr, FILHSZ) < 0) - return -1; - - switch (file_hdr->f_magic) - { -#ifdef MC68MAGIC - case MC68MAGIC: -#endif -#ifdef NS32GMAGIC - case NS32GMAGIC: - case NS32SMAGIC: -#endif -#ifdef I386MAGIC - case I386MAGIC: -#endif -#ifdef CLIPPERMAGIC - case CLIPPERMAGIC: -#endif -#if defined (MC68KWRMAGIC) \ - && (!defined (MC68MAGIC) || MC68KWRMAGIC != MC68MAGIC) - case MC68KWRMAGIC: -#endif -#ifdef MC68KROMAGIC - case MC68KROMAGIC: - case MC68KPGMAGIC: -#endif -#ifdef MC88DGMAGIC - case MC88DGMAGIC: -#endif -#ifdef MC88MAGIC - case MC88MAGIC: -#endif -#ifdef I960ROMAGIC - case I960ROMAGIC: /* Intel 960 */ -#endif -#ifdef I960RWMAGIC - case I960RWMAGIC: /* Intel 960 */ -#endif - return file_hdr->f_nsyms; - - default: -#ifdef BADMAG - if (BADMAG(file_hdr)) - return -1; - else - return file_hdr->f_nsyms; -#else - return -1; -#endif - } -} -#endif - -/* Read the next symbol, swap it, and return it in both internal_syment - form, and coff_symbol form. Also return its first auxent, if any, - in internal_auxent form, and skip any other auxents. */ - -static void -read_one_sym (cs, sym, aux) - register struct coff_symbol *cs; - register struct internal_syment *sym; - register union internal_auxent *aux; -{ - int i; - - cs->c_symnum = symnum; - fread (temp_sym, local_symesz, 1, nlist_stream_global); - bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *)sym); - cs->c_naux = sym->n_numaux & 0xff; - if (cs->c_naux >= 1) - { - fread (temp_aux, local_auxesz, 1, nlist_stream_global); - bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass, - 0, cs->c_naux, (char *)aux); - /* If more than one aux entry, read past it (only the first aux - is important). */ - for (i = 1; i < cs->c_naux; i++) - fread (temp_aux, local_auxesz, 1, nlist_stream_global); - } - cs->c_name = getsymname (sym); - cs->c_value = sym->n_value; - cs->c_sclass = (sym->n_sclass & 0xff); - cs->c_secnum = sym->n_scnum; - cs->c_type = (unsigned) sym->n_type; - if (!SDB_TYPE (cs->c_type)) - cs->c_type = 0; - - symnum += 1 + cs->c_naux; -} - -/* Support for string table handling */ - -static char *stringtab = NULL; - -static int -init_stringtab (chan, offset) - int chan; - long offset; -{ - long length; - int val; - unsigned char lengthbuf[4]; - - free_stringtab (); - - /* If the file is stripped, the offset might be zero, indicating no - string table. Just return with `stringtab' set to null. */ - if (offset == 0) - return 0; - - if (lseek (chan, offset, 0) < 0) - return -1; - - val = myread (chan, (char *)lengthbuf, sizeof lengthbuf); - length = bfd_h_get_32 (symfile_bfd, lengthbuf); - - /* If no string table is needed, then the file may end immediately - after the symbols. Just return with `stringtab' set to null. */ - if (val != sizeof lengthbuf || length < sizeof lengthbuf) - return 0; - - stringtab = (char *) xmalloc (length); - memcpy (stringtab, &length, sizeof length); - if (length == sizeof length) /* Empty table -- just the count */ - return 0; - - val = myread (chan, stringtab + sizeof lengthbuf, length - sizeof lengthbuf); - if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0') - return -1; - - return 0; -} - -static void -free_stringtab () -{ - if (stringtab) - free (stringtab); - stringtab = NULL; -} - -static char * -getsymname (symbol_entry) - struct internal_syment *symbol_entry; -{ - static char buffer[SYMNMLEN+1]; - char *result; - - if (symbol_entry->_n._n_n._n_zeroes == 0) - { - result = stringtab + symbol_entry->_n._n_n._n_offset; - } - else - { - strncpy (buffer, symbol_entry->_n._n_name, SYMNMLEN); - buffer[SYMNMLEN] = '\0'; - result = buffer; - } - return result; -} - -/* 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. */ - -char * -coff_getfilename (aux_entry) - union internal_auxent *aux_entry; -{ - static char buffer[BUFSIZ]; - register char *temp; - char *result; - - if (aux_entry->x_file.x_n.x_zeroes == 0) - strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset); - else - { - strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN); - buffer[FILNMLEN] = '\0'; - } - result = buffer; - if ((temp = strrchr (result, '/')) != NULL) - result = temp + 1; - return (result); -} - -/* Support for line number handling */ -static char *linetab = NULL; -static long linetab_offset; -static unsigned long linetab_size; - -/* Read in all the line numbers for fast lookups later. Leave them in - external (unswapped) format in memory; we'll swap them as we enter - them into GDB's data structures. */ - -static int -init_lineno (chan, offset, size) - int chan; - long offset; - int size; -{ - int val; - - linetab_offset = offset; - linetab_size = size; - - free_linetab(); - - if (size == 0) - return 0; - - if (lseek (chan, offset, 0) < 0) - return -1; - - /* Allocate the desired table, plus a sentinel */ - linetab = (char *) xmalloc (size + local_linesz); - - val = myread (chan, linetab, size); - if (val != size) - return -1; - - /* Terminate it with an all-zero sentinel record */ - memset (linetab + size, 0, local_linesz); - - return 0; -} - -static void -free_linetab () -{ - if (linetab) - free (linetab); - linetab = NULL; -} - -#if !defined (L_LNNO32) -#define L_LNNO32(lp) ((lp)->l_lnno) -#endif - -static void -enter_linenos (file_offset, first_line, last_line) - long file_offset; - register int first_line; - register int last_line; -{ - register char *rawptr; - struct internal_lineno lptr; - - if (file_offset < linetab_offset) - { - complain (&lineno_complaint, file_offset); - if (file_offset > linetab_size) /* Too big to be an offset? */ - return; - file_offset += linetab_offset; /* Try reading at that linetab offset */ - } - - rawptr = &linetab[file_offset - linetab_offset]; - - /* skip first line entry for each function */ - rawptr += local_linesz; - /* line numbers start at one for the first line of the function */ - first_line--; - - for (;;) { - bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr); - rawptr += local_linesz; - /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */ - if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line) - coff_record_line (first_line + L_LNNO32 (&lptr), lptr.l_addr.l_paddr); - else - break; - } -} - -static void -patch_type (type, real_type) - struct type *type; - struct type *real_type; -{ - register struct type *target = TYPE_TARGET_TYPE (type); - register struct type *real_target = TYPE_TARGET_TYPE (real_type); - int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field); - - TYPE_LENGTH (target) = TYPE_LENGTH (real_target); - TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target); - TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size); - - memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size); - - if (TYPE_NAME (real_target)) - { - if (TYPE_NAME (target)) - free (TYPE_NAME (target)); - TYPE_NAME (target) = concat (TYPE_NAME (real_target), NULL); - } -} - -/* Patch up all appropriate typedef symbols in the opaque_type_chains - so that they can be used to print out opaque data structures properly. */ - -static void -patch_opaque_types (s) - struct symtab *s; -{ - register struct block *b; - register int i; - register struct symbol *real_sym; - - /* Go through the per-file symbols only */ - b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); - for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--) - { - /* Find completed typedefs to use to fix opaque ones. - Remove syms from the chain when their types are stored, - but search the whole chain, as there may be several syms - from different files with the same name. */ - real_sym = BLOCK_SYM (b, i); - if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF && - SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE && - TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR && - TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0) - { - register char *name = SYMBOL_NAME (real_sym); - register int hash = hashname (name); - register struct symbol *sym, *prev; - - prev = 0; - for (sym = opaque_type_chain[hash]; sym;) - { - if (name[0] == SYMBOL_NAME (sym)[0] && - STREQ (name + 1, SYMBOL_NAME (sym) + 1)) - { - if (prev) - { - SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym); - } - else - { - opaque_type_chain[hash] = SYMBOL_VALUE_CHAIN (sym); - } - - patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym)); - - if (prev) - { - sym = SYMBOL_VALUE_CHAIN (prev); - } - else - { - sym = opaque_type_chain[hash]; - } - } - else - { - prev = sym; - sym = SYMBOL_VALUE_CHAIN (sym); - } - } - } - } -} - -static struct symbol * -process_coff_symbol (cs, aux, objfile) - register struct coff_symbol *cs; - register union internal_auxent *aux; - struct objfile *objfile; -{ - register struct symbol *sym - = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - char *name; - - 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)); - - /* default assumptions */ - SYMBOL_VALUE (sym) = cs->c_value; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - - if (ISFCN (cs->c_type)) - { -#if 0 - /* FIXME: This has NOT been tested. The DBX version has.. */ - /* Generate a template for the type of this function. The - types of the arguments will be added as we read the symbol - table. */ - struct type *new = (struct type *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct type)); - - memcpy (new, lookup_function_type (decode_function_type (cs, cs->c_type, aux)), - sizeof(struct type)); - SYMBOL_TYPE (sym) = new; - in_function_type = SYMBOL_TYPE(sym); -#else - SYMBOL_TYPE(sym) = - lookup_function_type (decode_function_type (cs, cs->c_type, aux)); -#endif - - SYMBOL_CLASS (sym) = LOC_BLOCK; - if (cs->c_sclass == C_STAT) - add_symbol_to_list (sym, &file_symbols); - else if (cs->c_sclass == C_EXT) - add_symbol_to_list (sym, &global_symbols); - } - else - { - SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux); - switch (cs->c_sclass) - { - case C_NULL: - break; - - case C_AUTO: - SYMBOL_CLASS (sym) = LOC_LOCAL; - add_symbol_to_list (sym, &local_symbols); - break; - - case C_EXT: - SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value; - add_symbol_to_list (sym, &global_symbols); - break; - - case C_STAT: - SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value; - if (within_function) { - /* Static symbol of local scope */ - add_symbol_to_list (sym, &local_symbols); - } - else { - /* Static symbol at top level of file */ - add_symbol_to_list (sym, &file_symbols); - } - break; - -#ifdef C_GLBLREG /* AMD coff */ - case C_GLBLREG: -#endif - case C_REG: - SYMBOL_CLASS (sym) = LOC_REGISTER; - SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM(cs->c_value); - add_symbol_to_list (sym, &local_symbols); - break; - - case C_LABEL: - break; - - case C_ARG: - SYMBOL_CLASS (sym) = LOC_ARG; -#if 0 - /* FIXME: This has not been tested. */ - /* Add parameter to function. */ - add_param_to_type(&in_function_type,sym); -#endif - add_symbol_to_list (sym, &local_symbols); -#if !defined (BELIEVE_PCC_PROMOTION) && (TARGET_BYTE_ORDER == BIG_ENDIAN) - { - /* If PCC says a parameter is a short or a char, - aligned on an int boundary, realign it to the "little end" - of the int. */ - struct type *temptype; - temptype = lookup_fundamental_type (current_objfile, FT_INTEGER); - if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype) - && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT - && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype)) - { - SYMBOL_VALUE (sym) += - TYPE_LENGTH (temptype) - - TYPE_LENGTH (SYMBOL_TYPE (sym)); - } - } -#endif - break; - - case C_REGPARM: - SYMBOL_CLASS (sym) = LOC_REGPARM; - SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM(cs->c_value); - add_symbol_to_list (sym, &local_symbols); -#if !defined (BELIEVE_PCC_PROMOTION) - /* FIXME: This should retain the current type, since it's just - a register value. gnu@adobe, 26Feb93 */ - { - /* If PCC says a parameter is a short or a char, - it is really an int. */ - struct type *temptype; - temptype = - lookup_fundamental_type (current_objfile, FT_INTEGER); - if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype) - && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT) - { - SYMBOL_TYPE (sym) = - (TYPE_UNSIGNED (SYMBOL_TYPE (sym)) - ? lookup_fundamental_type (current_objfile, - FT_UNSIGNED_INTEGER) - : temptype); - } - } -#endif - break; - - case C_TPDEF: - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - - /* If type has no name, give it one */ - if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) - { - if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC) - { - /* If we are giving a name to a type such as "pointer to - foo" or "function returning foo", we better not set - the TYPE_NAME. If the program contains "typedef char - *caddr_t;", we don't want all variables of type char - * to print as caddr_t. This is not just a - consequence of GDB's type management; CC and GCC (at - least through version 2.4) both output variables of - either type char * or caddr_t with the type - refering to the C_TPDEF symbol for caddr_t. If a future - compiler cleans this up it GDB is not ready for it - yet, but if it becomes ready we somehow need to - disable this check (without breaking the PCC/GCC2.4 - case). - - Sigh. - - Fortunately, this check seems not to be necessary - for anything except pointers or functions. */ - ; - } - else - TYPE_NAME (SYMBOL_TYPE (sym)) = - concat (SYMBOL_NAME (sym), NULL); - } - - /* Keep track of any type which points to empty structured type, - so it can be filled from a definition from another file. A - simple forward reference (TYPE_CODE_UNDEF) is not an - empty structured type, though; the forward references - work themselves out via the magic of coff_lookup_type. */ - if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR && - TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 && - TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) != - TYPE_CODE_UNDEF) - { - register int i = hashname (SYMBOL_NAME (sym)); - - SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i]; - opaque_type_chain[i] = sym; - } - add_symbol_to_list (sym, &file_symbols); - break; - - case C_STRTAG: - case C_UNTAG: - case C_ENTAG: - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; - - /* Some compilers try to be helpful by inventing "fake" - names for anonymous enums, structures, and unions, like - "~0fake" or ".0fake". Thanks, but no thanks... */ - if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0) - if (SYMBOL_NAME(sym) != NULL - && *SYMBOL_NAME(sym) != '~' - && *SYMBOL_NAME(sym) != '.') - TYPE_TAG_NAME (SYMBOL_TYPE (sym)) = - concat (SYMBOL_NAME (sym), NULL); - - add_symbol_to_list (sym, &file_symbols); - break; - - default: - break; - } - } - return sym; -} - -/* Decode a coff type specifier; - return the type that is meant. */ - -static -struct type * -decode_type (cs, c_type, aux) - register struct coff_symbol *cs; - unsigned int c_type; - register union internal_auxent *aux; -{ - register struct type *type = 0; - unsigned int new_c_type; - - if (c_type & ~N_BTMASK) - { - new_c_type = DECREF (c_type); - if (ISPTR (c_type)) - { - type = decode_type (cs, new_c_type, aux); - type = lookup_pointer_type (type); - } - else if (ISFCN (c_type)) - { - type = decode_type (cs, new_c_type, aux); - type = lookup_function_type (type); - } - else if (ISARY (c_type)) - { - int i, n; - register unsigned short *dim; - struct type *base_type, *index_type, *range_type; - - /* Define an array type. */ - /* auxent refers to array, not base type */ - if (aux->x_sym.x_tagndx.l == 0) - cs->c_naux = 0; - - /* shift the indices down */ - dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0]; - i = 1; - n = dim[0]; - for (i = 0; *dim && i < DIMNUM - 1; i++, dim++) - *dim = *(dim + 1); - *dim = 0; - - base_type = decode_type (cs, new_c_type, aux); - index_type = lookup_fundamental_type (current_objfile, FT_INTEGER); - range_type = - create_range_type ((struct type *) NULL, index_type, 0, n - 1); - type = - create_array_type ((struct type *) NULL, base_type, range_type); - } - return type; - } - - /* Reference to existing type. This only occurs with the - struct, union, and enum types. EPI a29k coff - fakes us out by producing aux entries with a nonzero - x_tagndx for definitions of structs, unions, and enums, so we - have to check the c_sclass field. SCO 3.2v4 cc gets confused - with pointers to pointers to defined structs, and generates - negative x_tagndx fields. */ - if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0) - { - if (cs->c_sclass != C_STRTAG - && cs->c_sclass != C_UNTAG - && cs->c_sclass != C_ENTAG - && aux->x_sym.x_tagndx.l >= 0) - { - type = coff_alloc_type (aux->x_sym.x_tagndx.l); - return type; - } else { - complain (&tagndx_bad_complaint, cs->c_name); - /* And fall through to decode_base_type... */ - } - } - - return decode_base_type (cs, BTYPE (c_type), aux); -} - -/* Decode a coff type specifier for function definition; - return the type that the function returns. */ - -static -struct type * -decode_function_type (cs, c_type, aux) - register struct coff_symbol *cs; - unsigned int c_type; - register union internal_auxent *aux; -{ - if (aux->x_sym.x_tagndx.l == 0) - cs->c_naux = 0; /* auxent refers to function, not base type */ - - return decode_type (cs, DECREF (c_type), aux); -} - -/* basic C types */ - -static -struct type * -decode_base_type (cs, c_type, aux) - register struct coff_symbol *cs; - unsigned int c_type; - register union internal_auxent *aux; -{ - struct type *type; - - switch (c_type) - { - case T_NULL: - /* shows up with "void (*foo)();" structure members */ - return lookup_fundamental_type (current_objfile, FT_VOID); - -#if 0 -/* DGUX actually defines both T_ARG and T_VOID to the same value. */ -#ifdef T_ARG - case T_ARG: - /* Shows up in DGUX, I think. Not sure where. */ - return lookup_fundamental_type (current_objfile, FT_VOID); /* shouldn't show up here */ -#endif -#endif /* 0 */ - -#ifdef T_VOID - case T_VOID: - /* Intel 960 COFF has this symbol and meaning. */ - return lookup_fundamental_type (current_objfile, FT_VOID); -#endif - - case T_CHAR: - return lookup_fundamental_type (current_objfile, FT_CHAR); - - case T_SHORT: - return lookup_fundamental_type (current_objfile, FT_SHORT); - - case T_INT: - return lookup_fundamental_type (current_objfile, FT_INTEGER); - - case T_LONG: - return lookup_fundamental_type (current_objfile, FT_LONG); - - case T_FLOAT: - return lookup_fundamental_type (current_objfile, FT_FLOAT); - - case T_DOUBLE: - return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT); - - case T_STRUCT: - if (cs->c_naux != 1) - { - /* anonymous structure type */ - type = coff_alloc_type (cs->c_symnum); - TYPE_CODE (type) = TYPE_CODE_STRUCT; - TYPE_NAME (type) = NULL; - /* This used to set the tag to "". But I think setting it - to NULL is right, and the printing code can print it as - "struct {...}". */ - TYPE_TAG_NAME (type) = NULL; - INIT_CPLUS_SPECIFIC(type); - TYPE_LENGTH (type) = 0; - TYPE_FIELDS (type) = 0; - TYPE_NFIELDS (type) = 0; - } - else - { - type = coff_read_struct_type (cs->c_symnum, - aux->x_sym.x_misc.x_lnsz.x_size, - aux->x_sym.x_fcnary.x_fcn.x_endndx.l); - } - return type; - - case T_UNION: - if (cs->c_naux != 1) - { - /* anonymous union type */ - type = coff_alloc_type (cs->c_symnum); - TYPE_NAME (type) = NULL; - /* This used to set the tag to "". But I think setting it - to NULL is right, and the printing code can print it as - "union {...}". */ - TYPE_TAG_NAME (type) = NULL; - INIT_CPLUS_SPECIFIC(type); - TYPE_LENGTH (type) = 0; - TYPE_FIELDS (type) = 0; - TYPE_NFIELDS (type) = 0; - } - else - { - type = coff_read_struct_type (cs->c_symnum, - aux->x_sym.x_misc.x_lnsz.x_size, - aux->x_sym.x_fcnary.x_fcn.x_endndx.l); - } - TYPE_CODE (type) = TYPE_CODE_UNION; - return type; - - case T_ENUM: - if (cs->c_naux != 1) - { - /* anonymous enum type */ - type = coff_alloc_type (cs->c_symnum); - TYPE_CODE (type) = TYPE_CODE_ENUM; - TYPE_NAME (type) = NULL; - /* This used to set the tag to "". But I think setting it - to NULL is right, and the printing code can print it as - "enum {...}". */ - TYPE_TAG_NAME (type) = NULL; - TYPE_LENGTH (type) = 0; - TYPE_FIELDS (type) = 0; - TYPE_NFIELDS(type) = 0; - } - else - { - type = coff_read_enum_type (cs->c_symnum, - aux->x_sym.x_misc.x_lnsz.x_size, - aux->x_sym.x_fcnary.x_fcn.x_endndx.l); - } - return type; - - case T_MOE: - /* shouldn't show up here */ - break; - - case T_UCHAR: - return lookup_fundamental_type (current_objfile, FT_UNSIGNED_CHAR); - - case T_USHORT: - return lookup_fundamental_type (current_objfile, FT_UNSIGNED_SHORT); - - case T_UINT: - return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER); - - case T_ULONG: - return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG); - } - complain (&unexpected_type_complaint, cs->c_name); - return lookup_fundamental_type (current_objfile, FT_VOID); -} - -/* This page contains subroutines of read_type. */ - -/* Read the description of a structure (or union type) - and return an object describing the type. */ - -static struct type * -coff_read_struct_type (index, length, lastsym) - int index; - int length; - int lastsym; -{ - struct nextfield - { - struct nextfield *next; - struct field field; - }; - - register struct type *type; - register struct nextfield *list = 0; - struct nextfield *new; - int nfields = 0; - register int n; - char *name; - struct coff_symbol member_sym; - register struct coff_symbol *ms = &member_sym; - struct internal_syment sub_sym; - union internal_auxent sub_aux; - int done = 0; - - type = coff_alloc_type (index); - TYPE_CODE (type) = TYPE_CODE_STRUCT; - INIT_CPLUS_SPECIFIC(type); - TYPE_LENGTH (type) = length; - - while (!done && symnum < lastsym && symnum < nlist_nsyms_global) - { - read_one_sym (ms, &sub_sym, &sub_aux); - name = ms->c_name; - name = EXTERNAL_NAME (name, current_objfile->obfd); - - switch (ms->c_sclass) - { - case C_MOS: - case C_MOU: - - /* Get space to record the next field's data. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - /* Save the data. */ - list->field.name = savestring (name, strlen (name)); - list->field.type = decode_type (ms, ms->c_type, &sub_aux); - list->field.bitpos = 8 * ms->c_value; - list->field.bitsize = 0; - nfields++; - break; - - case C_FIELD: - - /* Get space to record the next field's data. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; - - /* Save the data. */ - list->field.name = savestring (name, strlen (name)); - 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; - nfields++; - break; - - case C_EOS: - done = 1; - break; - } - } - /* Now create the vector of fields, and record how big it is. */ - - TYPE_NFIELDS (type) = nfields; - TYPE_FIELDS (type) = (struct field *) - TYPE_ALLOC (type, sizeof (struct field) * nfields); - - /* Copy the saved-up fields into the field vector. */ - - for (n = nfields; list; list = list->next) - TYPE_FIELD (type, --n) = list->field; - - return type; -} - -/* Read a definition of an enumeration type, - and create and return a suitable type object. - Also defines the symbols that represent the values of the type. */ - -/* ARGSUSED */ -static struct type * -coff_read_enum_type (index, length, lastsym) - int index; - int length; - int lastsym; -{ - register struct symbol *sym; - register struct type *type; - int nsyms = 0; - int done = 0; - struct pending **symlist; - struct coff_symbol member_sym; - register struct coff_symbol *ms = &member_sym; - struct internal_syment sub_sym; - union internal_auxent sub_aux; - struct pending *osyms, *syms; - int o_nsyms; - register int n; - char *name; - - type = coff_alloc_type (index); - if (within_function) - symlist = &local_symbols; - else - symlist = &file_symbols; - osyms = *symlist; - o_nsyms = osyms ? osyms->nsyms : 0; - - while (!done && symnum < lastsym && symnum < nlist_nsyms_global) - { - read_one_sym (ms, &sub_sym, &sub_aux); - name = ms->c_name; - name = EXTERNAL_NAME (name, current_objfile->obfd); - - switch (ms->c_sclass) - { - case C_MOE: - sym = (struct symbol *) xmalloc (sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - - SYMBOL_NAME (sym) = savestring (name, strlen (name)); - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_VALUE (sym) = ms->c_value; - add_symbol_to_list (sym, symlist); - nsyms++; - break; - - case C_EOS: - /* Sometimes the linker (on 386/ix 2.0.2 at least) screws - up the count of how many symbols to read. So stop - on .eos. */ - done = 1; - break; - } - } - - /* Now fill in the fields of the type-structure. */ - - if (length > 0) - TYPE_LENGTH (type) = length; - else - TYPE_LENGTH (type) = TARGET_INT_BIT / TARGET_CHAR_BIT; /* Assume ints */ - TYPE_CODE (type) = TYPE_CODE_ENUM; - TYPE_NFIELDS (type) = nsyms; - TYPE_FIELDS (type) = (struct field *) - TYPE_ALLOC (type, sizeof (struct field) * nsyms); - - /* Find the symbols for the values 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_VALUE (type, n) = 0; - TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym); - TYPE_FIELD_BITSIZE (type, n) = 0; - } - if (syms == osyms) - break; - } - - return type; -} - -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-1)); - - for (i = 0; i < SECT_OFF_MAX; i++) - ANOFFSET (section_offsets, i) = addr; - - return section_offsets; -} - -/* Register our ability to parse symbols for coff BFD files */ - -static struct sym_fns coff_sym_fns = -{ - bfd_target_coff_flavour, - coff_new_init, /* sym_new_init: init anything gbl to entire symtab */ - 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 */ - NULL /* next: pointer to next struct sym_fns */ -}; - -void -_initialize_coffread () -{ - add_symtab_fns(&coff_sym_fns); -} diff --git a/gnu/usr.bin/gdb/gdb/command.c b/gnu/usr.bin/gdb/gdb/command.c deleted file mode 100644 index 5d42886..0000000 --- a/gnu/usr.bin/gdb/gdb/command.c +++ /dev/null @@ -1,1331 +0,0 @@ -/* Handle lists of commands, their decoding and documentation, for GDB. - Copyright 1986, 1989, 1990, 1991 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include "gdbcmd.h" -#include "symtab.h" -#include "value.h" -#include -#include - -/* Prototypes for local functions */ - -static void -undef_cmd_error PARAMS ((char *, char *)); - -static void -show_user PARAMS ((char *, int)); - -static void -show_user_1 PARAMS ((struct cmd_list_element *, GDB_FILE *)); - -static void -make_command PARAMS ((char *, int)); - -static void -shell_escape PARAMS ((char *, int)); - -static int -parse_binary_operation PARAMS ((char *)); - -static void -print_doc_line PARAMS ((GDB_FILE *, char *)); - -/* Add element named NAME. - CLASS is the top level category into which commands are broken down - for "help" purposes. - FUN should be the function to execute the command; - it will get a character string as argument, with leading - and trailing blanks already eliminated. - - DOC is a documentation string for the command. - Its first line should be a complete sentence. - 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. */ - -struct cmd_list_element * -add_cmd (name, class, fun, doc, list) - char *name; - enum command_class class; - void (*fun) PARAMS ((char *, int)); - char *doc; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c - = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element)); - - delete_cmd (name, list); - c->next = *list; - c->name = name; - c->class = class; - c->function.cfunc = fun; - c->doc = doc; - c->prefixlist = 0; - c->prefixname = (char *)NULL; - c->allow_unknown = 0; - c->hook = 0; - c->hookee = 0; - c->cmd_pointer = 0; - c->abbrev_flag = 0; - c->type = not_set_cmd; - c->completer = make_symbol_completion_list; - c->var = 0; - c->var_type = var_boolean; - c->user_commands = 0; - *list = c; - return c; -} - -/* Same as above, except that the abbrev_flag is set. */ - -#if 0 /* Currently unused */ - -struct cmd_list_element * -add_abbrev_cmd (name, class, fun, doc, list) - char *name; - enum command_class class; - void (*fun) PARAMS ((char *, int)); - char *doc; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c - = add_cmd (name, class, fun, doc, list); - - c->abbrev_flag = 1; - return c; -} - -#endif - -struct cmd_list_element * -add_alias_cmd (name, oldname, class, abbrev_flag, list) - char *name; - char *oldname; - enum command_class class; - int abbrev_flag; - struct cmd_list_element **list; -{ - /* Must do this since lookup_cmd tries to side-effect its first arg */ - char *copied_name; - register struct cmd_list_element *old; - register struct cmd_list_element *c; - copied_name = (char *) alloca (strlen (oldname) + 1); - strcpy (copied_name, oldname); - old = lookup_cmd (&copied_name, *list, "", 1, 1); - - if (old == 0) - { - delete_cmd (name, list); - return 0; - } - - c = add_cmd (name, class, old->function.cfunc, old->doc, list); - c->prefixlist = old->prefixlist; - c->prefixname = old->prefixname; - c->allow_unknown = old->allow_unknown; - c->abbrev_flag = abbrev_flag; - c->cmd_pointer = old; - return c; -} - -/* Like add_cmd but adds an element for a command prefix: - a name that should be followed by a subcommand to be looked up - in another command list. PREFIXLIST should be the address - of the variable containing that list. */ - -struct cmd_list_element * -add_prefix_cmd (name, class, fun, doc, prefixlist, prefixname, - allow_unknown, list) - char *name; - enum command_class class; - void (*fun) PARAMS ((char *, int)); - char *doc; - struct cmd_list_element **prefixlist; - char *prefixname; - int allow_unknown; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); - c->prefixlist = prefixlist; - c->prefixname = prefixname; - c->allow_unknown = allow_unknown; - return c; -} - -/* Like add_prefix_cmd but sets the abbrev_flag on the new command. */ - -struct cmd_list_element * -add_abbrev_prefix_cmd (name, class, fun, doc, prefixlist, prefixname, - allow_unknown, list) - char *name; - enum command_class class; - void (*fun) PARAMS ((char *, int)); - char *doc; - struct cmd_list_element **prefixlist; - char *prefixname; - int allow_unknown; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list); - c->prefixlist = prefixlist; - c->prefixname = prefixname; - c->allow_unknown = allow_unknown; - c->abbrev_flag = 1; - return c; -} - -/* This is an empty "cfunc". */ -void -not_just_help_class_command (args, from_tty) - char *args; - int from_tty; -{ -} - -/* This is an empty "sfunc". */ -static void empty_sfunc PARAMS ((char *, int, struct cmd_list_element *)); - -static void -empty_sfunc (args, from_tty, c) - char *args; - int from_tty; - struct cmd_list_element *c; -{ -} - -/* Add element named NAME to command list LIST (the list for set - or some sublist thereof). - CLASS is as in add_cmd. - VAR_TYPE is the kind of thing we are setting. - VAR is address of the variable being controlled by this command. - DOC is the documentation string. */ - -struct cmd_list_element * -add_set_cmd (name, class, var_type, var, doc, list) - char *name; - enum command_class class; - var_types var_type; - char *var; - char *doc; - struct cmd_list_element **list; -{ - struct cmd_list_element *c - = add_cmd (name, class, NO_FUNCTION, doc, list); - - c->type = set_cmd; - c->var_type = var_type; - c->var = var; - /* This needs to be something besides NO_FUNCTION so that this isn't - treated as a help class. */ - c->function.sfunc = empty_sfunc; - return c; -} - -/* Where SETCMD has already been added, add the corresponding show - command to LIST and return a pointer to it. */ -struct cmd_list_element * -add_show_from_set (setcmd, list) - struct cmd_list_element *setcmd; - struct cmd_list_element **list; -{ - struct cmd_list_element *showcmd = - (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element)); - - memcpy (showcmd, setcmd, sizeof (struct cmd_list_element)); - delete_cmd (showcmd->name, list); - showcmd->type = show_cmd; - - /* Replace "set " at start of docstring with "show ". */ - if (setcmd->doc[0] == 'S' && setcmd->doc[1] == 'e' - && setcmd->doc[2] == 't' && setcmd->doc[3] == ' ') - showcmd->doc = concat ("Show ", setcmd->doc + 4, NULL); - else - fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n"); - - showcmd->next = *list; - *list = showcmd; - return showcmd; -} - -/* Remove the command named NAME from the command list. */ - -void -delete_cmd (name, list) - char *name; - struct cmd_list_element **list; -{ - register struct cmd_list_element *c; - struct cmd_list_element *p; - - while (*list && STREQ ((*list)->name, name)) - { - if ((*list)->hookee) - (*list)->hookee->hook = 0; /* Hook slips out of its mouth */ - p = (*list)->next; - free ((PTR)*list); - *list = p; - } - - if (*list) - for (c = *list; c->next;) - { - if (STREQ (c->next->name, name)) - { - if (c->next->hookee) - c->next->hookee->hook = 0; /* hooked cmd gets away. */ - p = c->next->next; - free ((PTR)c->next); - c->next = p; - } - else - c = c->next; - } -} - -/* This command really has to deal with two things: - * 1) I want documentation on *this string* (usually called by - * "help commandname"). - * 2) I want documentation on *this list* (usually called by - * giving a command that requires subcommands. Also called by saying - * just "help".) - * - * I am going to split this into two seperate comamnds, help_cmd and - * help_list. - */ - -void -help_cmd (command, stream) - char *command; - GDB_FILE *stream; -{ - struct cmd_list_element *c; - extern struct cmd_list_element *cmdlist; - - if (!command) - { - help_list (cmdlist, "", all_classes, stream); - return; - } - - c = lookup_cmd (&command, cmdlist, "", 0, 0); - - if (c == 0) - return; - - /* There are three cases here. - If c->prefixlist is nonzero, we have a prefix command. - Print its documentation, then list its subcommands. - - If c->function is nonzero, we really have a command. - Print its documentation and return. - - If c->function is zero, we have a class name. - Print its documentation (as if it were a command) - and then set class to the number of this class - so that the commands in the class will be listed. */ - - fputs_filtered (c->doc, stream); - fputs_filtered ("\n", stream); - - if (c->prefixlist == 0 && c->function.cfunc != NULL) - return; - fprintf_filtered (stream, "\n"); - - /* If this is a prefix command, print it's subcommands */ - if (c->prefixlist) - help_list (*c->prefixlist, c->prefixname, all_commands, stream); - - /* If this is a class name, print all of the commands in the class */ - if (c->function.cfunc == NULL) - help_list (cmdlist, "", c->class, stream); - - if (c->hook) - fprintf_filtered (stream, "\nThis command has a hook defined: %s\n", - c->hook->name); -} - -/* - * Get a specific kind of help on a command list. - * - * LIST is the list. - * CMDTYPE is the prefix to use in the title string. - * CLASS is the class with which to list the nodes of this list (see - * documentation for help_cmd_list below), As usual, ALL_COMMANDS for - * everything, ALL_CLASSES for just classes, and non-negative for only things - * in a specific class. - * and STREAM is the output stream on which to print things. - * If you call this routine with a class >= 0, it recurses. - */ -void -help_list (list, cmdtype, class, stream) - struct cmd_list_element *list; - char *cmdtype; - enum command_class class; - GDB_FILE *stream; -{ - int len; - char *cmdtype1, *cmdtype2; - - /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub" */ - len = strlen (cmdtype); - cmdtype1 = (char *) alloca (len + 1); - cmdtype1[0] = 0; - cmdtype2 = (char *) alloca (len + 4); - cmdtype2[0] = 0; - if (len) - { - cmdtype1[0] = ' '; - strncpy (cmdtype1 + 1, cmdtype, len - 1); - cmdtype1[len] = 0; - strncpy (cmdtype2, cmdtype, len - 1); - strcpy (cmdtype2 + len - 1, " sub"); - } - - if (class == all_classes) - fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2); - else - fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2); - - help_cmd_list (list, class, cmdtype, (int)class >= 0, stream); - - if (class == all_classes) - fprintf_filtered (stream, "\n\ -Type \"help%s\" followed by a class name for a list of commands in that class.", - cmdtype1); - - fprintf_filtered (stream, "\n\ -Type \"help%s\" followed by %scommand name for full documentation.\n\ -Command name abbreviations are allowed if unambiguous.\n", - cmdtype1, cmdtype2); -} - -/* Print only the first line of STR on STREAM. */ -static void -print_doc_line (stream, str) - GDB_FILE *stream; - char *str; -{ - static char *line_buffer = 0; - static int line_size; - register char *p; - - if (!line_buffer) - { - line_size = 80; - line_buffer = (char *) xmalloc (line_size); - } - - p = str; - while (*p && *p != '\n' && *p != '.' && *p != ',') - p++; - if (p - str > line_size - 1) - { - line_size = p - str + 1; - free ((PTR)line_buffer); - line_buffer = (char *) xmalloc (line_size); - } - strncpy (line_buffer, str, p - str); - line_buffer[p - str] = '\0'; - if (islower (line_buffer[0])) - line_buffer[0] = toupper (line_buffer[0]); - fputs_filtered (line_buffer, stream); -} - -/* - * Implement a help command on command list LIST. - * RECURSE should be non-zero if this should be done recursively on - * all sublists of LIST. - * PREFIX is the prefix to print before each command name. - * STREAM is the stream upon which the output should be written. - * CLASS should be: - * A non-negative class number to list only commands in that - * class. - * ALL_COMMANDS to list all commands in list. - * ALL_CLASSES to list all classes in list. - * - * Note that RECURSE will be active on *all* sublists, not just the - * ones selected by the criteria above (ie. the selection mechanism - * is at the low level, not the high-level). - */ -void -help_cmd_list (list, class, prefix, recurse, stream) - struct cmd_list_element *list; - enum command_class class; - char *prefix; - int recurse; - GDB_FILE *stream; -{ - register struct cmd_list_element *c; - - for (c = list; c; c = c->next) - { - if (c->abbrev_flag == 0 && - (class == all_commands - || (class == all_classes && c->function.cfunc == NULL) - || (class == c->class && c->function.cfunc != NULL))) - { - fprintf_filtered (stream, "%s%s -- ", prefix, c->name); - print_doc_line (stream, c->doc); - fputs_filtered ("\n", stream); - } - if (recurse - && c->prefixlist != 0 - && c->abbrev_flag == 0) - help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream); - } -} - -/* 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 - which the last word was matched, and will return a pointer to the cmd - list element which the text matches. It will return NULL if no match at - all was possible. It will return -1 (cast appropriately, ick) if ambigous - matches are possible; in this case *RESULT_LIST will be set to point to - the list in which there are ambiguous choices (and *TEXT will be set to - the ambiguous text string). - - If the located command was an abbreviation, this routine returns the base - command of the abbreviation. - - It does no error reporting whatsoever; control will always return - to the superior routine. - - In the case of an ambiguous return (-1), *RESULT_LIST will be set to point - at the prefix_command (ie. the best match) *or* (special case) will be NULL - if no prefix command was ever found. For example, in the case of "info a", - "info" matches without ambiguity, but "a" could be "args" or "address", so - *RESULT_LIST is set to the cmd_list_element for "info". So in this case - RESULT_LIST should not be interpeted as a pointer to the beginning of a - list; it simply points to a specific command. In the case of an ambiguous - return *TEXT is advanced past the last non-ambiguous prefix (e.g. - "info t" can be "info types" or "info target"; upon return *TEXT has been - advanced past "info "). - - If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise - affect the operation). - - This routine does *not* modify the text pointed to by TEXT. - - If IGNORE_HELP_CLASSES is nonzero, ignore any command list elements which - are actually help classes rather than commands (i.e. the function field of - the struct cmd_list_element is NULL). */ - -struct cmd_list_element * -lookup_cmd_1 (text, clist, result_list, ignore_help_classes) - char **text; - struct cmd_list_element *clist, **result_list; - int ignore_help_classes; -{ - char *p, *command; - int len, tmp, nfound; - struct cmd_list_element *found, *c; - - while (**text == ' ' || **text == '\t') - (*text)++; - - /* Treating underscores as part of command words is important - so that "set args_foo()" doesn't get interpreted as - "set args _foo()". */ - for (p = *text; - *p && (isalnum(*p) || *p == '-' || *p == '_'); - p++) - ; - - /* If nothing but whitespace, return 0. */ - if (p == *text) - return 0; - - 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. */ - - command = (char *) alloca (len + 1); - for (tmp = 0; tmp < len; tmp++) - { - char x = (*text)[tmp]; - command[tmp] = isupper(x) ? tolower(x) : 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; - } - } - - /* If nothing matches, we have a simple failure. */ - if (nfound == 0) - return 0; - - if (nfound > 1) - { - if (result_list != NULL) - /* Will be modified in calling routine - if we know what the prefix command is. */ - *result_list = 0; - return (struct cmd_list_element *) -1; /* Ambiguous. */ - } - - /* We've matched something on this list. Move text pointer forward. */ - - *text = p; - - /* If this was an abbreviation, use the base command instead. */ - - if (found->cmd_pointer) - found = found->cmd_pointer; - - /* If we found a prefix command, keep looking. */ - - if (found->prefixlist) - { - c = lookup_cmd_1 (text, *found->prefixlist, result_list, - ignore_help_classes); - if (!c) - { - /* Didn't find anything; this is as far as we got. */ - if (result_list != NULL) - *result_list = clist; - return found; - } - else if (c == (struct cmd_list_element *) -1) - { - /* We've gotten this far properley, 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) - if (!*result_list) - /* This used to say *result_list = *found->prefixlist - If that was correct, need to modify the documentation - at the top of this function to clarify what is supposed - to be going on. */ - *result_list = found; - return c; - } - else - { - /* We matched! */ - return c; - } - } - else - { - if (result_list != NULL) - *result_list = clist; - return found; - } -} - -/* All this hair to move the space to the front of cmdtype */ - -static void -undef_cmd_error (cmdtype, q) - char *cmdtype, *q; -{ - error ("Undefined %scommand: \"%s\". Try \"help%s%.*s\".", - cmdtype, - q, - *cmdtype? " ": "", - strlen(cmdtype)-1, - cmdtype); -} - -/* Look up the contents of *LINE as a command in the command list LIST. - LIST is a chain of struct cmd_list_element's. - If it is found, return the struct cmd_list_element for that command - and update *LINE to point after the command name, at the first argument. - If not found, call error if ALLOW_UNKNOWN is zero - otherwise (or if error returns) return zero. - Call error if specified command is ambiguous, - unless ALLOW_UNKNOWN is negative. - CMDTYPE precedes the word "command" in the error message. - - If INGNORE_HELP_CLASSES is nonzero, ignore any command list - elements which are actually help classes rather than commands (i.e. - the function field of the struct cmd_list_element is 0). */ - -struct cmd_list_element * -lookup_cmd (line, list, cmdtype, allow_unknown, ignore_help_classes) - char **line; - struct cmd_list_element *list; - char *cmdtype; - int allow_unknown; - int ignore_help_classes; -{ - struct cmd_list_element *last_list = 0; - struct cmd_list_element *c = - lookup_cmd_1 (line, list, &last_list, ignore_help_classes); -#if 0 - /* This is wrong for complete_command. */ - char *ptr = (*line) + strlen (*line) - 1; - - /* Clear off trailing whitespace. */ - while (ptr >= *line && (*ptr == ' ' || *ptr == '\t')) - ptr--; - *(ptr + 1) = '\0'; -#endif - - if (!c) - { - if (!allow_unknown) - { - if (!*line) - error ("Lack of needed %scommand", cmdtype); - else - { - char *p = *line, *q; - - while (isalnum(*p) || *p == '-') - p++; - - q = (char *) alloca (p - *line + 1); - strncpy (q, *line, p - *line); - q[p-*line] = '\0'; - undef_cmd_error (cmdtype, q); - } - } - else - return 0; - } - else if (c == (struct cmd_list_element *) -1) - { - /* Ambigous. Local values should be off prefixlist or called - values. */ - int local_allow_unknown = (last_list ? last_list->allow_unknown : - allow_unknown); - char *local_cmdtype = last_list ? last_list->prefixname : cmdtype; - struct cmd_list_element *local_list = - (last_list ? *(last_list->prefixlist) : list); - - if (local_allow_unknown < 0) - { - if (last_list) - return last_list; /* Found something. */ - else - return 0; /* Found nothing. */ - } - else - { - /* Report as error. */ - int amb_len; - char ambbuf[100]; - - for (amb_len = 0; - ((*line)[amb_len] && (*line)[amb_len] != ' ' - && (*line)[amb_len] != '\t'); - amb_len++) - ; - - ambbuf[0] = 0; - for (c = local_list; c; c = c->next) - if (!strncmp (*line, c->name, amb_len)) - { - if (strlen (ambbuf) + strlen (c->name) + 6 < (int)sizeof ambbuf) - { - if (strlen (ambbuf)) - strcat (ambbuf, ", "); - strcat (ambbuf, c->name); - } - else - { - strcat (ambbuf, ".."); - break; - } - } - error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype, - *line, ambbuf); - return 0; /* lint */ - } - } - else - { - /* We've got something. It may still not be what the caller - wants (if this command *needs* a subcommand). */ - while (**line == ' ' || **line == '\t') - (*line)++; - - if (c->prefixlist && **line && !c->allow_unknown) - undef_cmd_error (c->prefixname, *line); - - /* Seems to be what he wants. Return it. */ - return c; - } - return 0; -} - -#if 0 -/* Look up the contents of *LINE as a command in the command list LIST. - LIST is a chain of struct cmd_list_element's. - If it is found, return the struct cmd_list_element for that command - and update *LINE to point after the command name, at the first argument. - If not found, call error if ALLOW_UNKNOWN is zero - otherwise (or if error returns) return zero. - Call error if specified command is ambiguous, - unless ALLOW_UNKNOWN is negative. - CMDTYPE precedes the word "command" in the error message. */ - -struct cmd_list_element * -lookup_cmd (line, list, cmdtype, allow_unknown) - char **line; - struct cmd_list_element *list; - char *cmdtype; - int allow_unknown; -{ - register char *p; - register struct cmd_list_element *c, *found; - int nfound; - char ambbuf[100]; - char *processed_cmd; - int i, cmd_len; - - /* Skip leading whitespace. */ - - while (**line == ' ' || **line == '\t') - (*line)++; - - /* Clear out trailing whitespace. */ - - p = *line + strlen (*line); - while (p != *line && (p[-1] == ' ' || p[-1] == '\t')) - p--; - *p = 0; - - /* Find end of command name. */ - - p = *line; - while (*p == '-' || isalnum(*p)) - p++; - - /* Look up the command name. - If exact match, keep that. - Otherwise, take command abbreviated, if unique. Note that (in my - opinion) a null string does *not* indicate ambiguity; simply the - end of the argument. */ - - if (p == *line) - { - if (!allow_unknown) - error ("Lack of needed %scommand", cmdtype); - return 0; - } - - /* Copy over to a local buffer, converting to lowercase on the way. - This is in case the command being parsed is a subcommand which - doesn't match anything, and that's ok. We want the original - untouched for the routine of the original command. */ - - processed_cmd = (char *) alloca (p - *line + 1); - for (cmd_len = 0; cmd_len < p - *line; cmd_len++) - { - char x = (*line)[cmd_len]; - if (isupper(x)) - processed_cmd[cmd_len] = tolower(x); - else - processed_cmd[cmd_len] = x; - } - processed_cmd[cmd_len] = '\0'; - - /* Check all possibilities in the current command list. */ - found = 0; - nfound = 0; - for (c = list; c; c = c->next) - { - if (!strncmp (processed_cmd, c->name, cmd_len)) - { - found = c; - nfound++; - if (c->name[cmd_len] == 0) - { - nfound = 1; - break; - } - } - } - - /* Report error for undefined command name. */ - - if (nfound != 1) - { - if (nfound > 1 && allow_unknown >= 0) - { - ambbuf[0] = 0; - for (c = list; c; c = c->next) - if (!strncmp (processed_cmd, c->name, cmd_len)) - { - if (strlen (ambbuf) + strlen (c->name) + 6 < sizeof ambbuf) - { - if (strlen (ambbuf)) - strcat (ambbuf, ", "); - strcat (ambbuf, c->name); - } - else - { - strcat (ambbuf, ".."); - break; - } - } - error ("Ambiguous %scommand \"%s\": %s.", cmdtype, - processed_cmd, ambbuf); - } - else if (!allow_unknown) - error ("Undefined %scommand: \"%s\".", cmdtype, processed_cmd); - return 0; - } - - /* Skip whitespace before the argument. */ - - while (*p == ' ' || *p == '\t') p++; - *line = p; - - if (found->prefixlist && *p) - { - c = lookup_cmd (line, *found->prefixlist, found->prefixname, - found->allow_unknown); - if (c) - return c; - } - - return found; -} -#endif - -/* Helper function for SYMBOL_COMPLETION_FUNCTION. */ - -/* Return a vector of char pointers which point to the different - possible completions in LIST of TEXT. - - WORD points in the same buffer as TEXT, and completions should be - returned relative to this position. For example, suppose TEXT is "foo" - and we want to complete to "foobar". If WORD is "oo", return - "oobar"; if WORD is "baz/foo", return "baz/foobar". */ - -char ** -complete_on_cmdlist (list, text, word) - struct cmd_list_element *list; - char *text; - char *word; -{ - struct cmd_list_element *ptr; - char **matchlist; - int sizeof_matchlist; - int matches; - int textlen = strlen (text); - - sizeof_matchlist = 10; - matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *)); - matches = 0; - - for (ptr = list; ptr; ptr = ptr->next) - if (!strncmp (ptr->name, text, textlen) - && !ptr->abbrev_flag - && (ptr->function.cfunc - || ptr->prefixlist)) - { - if (matches == sizeof_matchlist) - { - sizeof_matchlist *= 2; - matchlist = (char **) xrealloc ((char *)matchlist, - (sizeof_matchlist - * sizeof (char *))); - } - - matchlist[matches] = (char *) - xmalloc (strlen (word) + strlen (ptr->name) + 1); - if (word == text) - strcpy (matchlist[matches], ptr->name); - else if (word > text) - { - /* Return some portion of ptr->name. */ - strcpy (matchlist[matches], ptr->name + (word - text)); - } - else - { - /* Return some of text plus ptr->name. */ - strncpy (matchlist[matches], word, text - word); - matchlist[matches][text - word] = '\0'; - strcat (matchlist[matches], ptr->name); - } - ++matches; - } - - if (matches == 0) - { - free ((PTR)matchlist); - matchlist = 0; - } - else - { - matchlist = (char **) xrealloc ((char *)matchlist, ((matches + 1) - * sizeof (char *))); - matchlist[matches] = (char *) 0; - } - - return matchlist; -} - -static int -parse_binary_operation (arg) - char *arg; -{ - int length; - - if (!arg || !*arg) - return 1; - - length = strlen (arg); - - while (arg[length - 1] == ' ' || arg[length - 1] == '\t') - length--; - - if (!strncmp (arg, "on", length) - || !strncmp (arg, "1", length) - || !strncmp (arg, "yes", length)) - return 1; - else - if (!strncmp (arg, "off", length) - || !strncmp (arg, "0", length) - || !strncmp (arg, "no", length)) - return 0; - else - { - error ("\"on\" or \"off\" expected."); - return 0; - } -} - -/* Do a "set" or "show" command. ARG is NULL if no argument, or the text - of the argument, and FROM_TTY is nonzero if this command is being entered - directly by the user (i.e. these are just like any other - command). C is the command list element for the command. */ -void -do_setshow_command (arg, from_tty, c) - char *arg; - int from_tty; - struct cmd_list_element *c; -{ - if (c->type == set_cmd) - { - switch (c->var_type) - { - case var_string: - { - char *new; - char *p; - char *q; - int ch; - - if (arg == NULL) - arg = ""; - new = (char *) xmalloc (strlen (arg) + 2); - p = arg; q = new; - while ((ch = *p++) != '\000') - { - if (ch == '\\') - { - /* \ at end of argument is used after spaces - so they won't be lost. */ - /* This is obsolete now that we no longer strip - trailing whitespace and actually, the backslash - didn't get here in my test, readline or - something did something funky with a backslash - right before a newline. */ - if (*p == 0) - break; - ch = parse_escape (&p); - if (ch == 0) - break; /* C loses */ - else if (ch > 0) - *q++ = ch; - } - else - *q++ = ch; - } -#if 0 - if (*(p - 1) != '\\') - *q++ = ' '; -#endif - *q++ = '\0'; - new = (char *) xrealloc (new, q - new); - if (*(char **)c->var != NULL) - free (*(char **)c->var); - *(char **) c->var = new; - } - break; - case var_string_noescape: - if (arg == NULL) - arg = ""; - if (*(char **)c->var != NULL) - free (*(char **)c->var); - *(char **) c->var = savestring (arg, strlen (arg)); - break; - case var_filename: - if (arg == NULL) - error_no_arg ("filename to set it to."); - if (*(char **)c->var != NULL) - free (*(char **)c->var); - *(char **)c->var = tilde_expand (arg); - break; - case var_boolean: - *(int *) c->var = parse_binary_operation (arg); - break; - case var_uinteger: - if (arg == NULL) - error_no_arg ("integer to set it to."); - *(unsigned int *) c->var = parse_and_eval_address (arg); - if (*(unsigned int *) c->var == 0) - *(unsigned int *) c->var = UINT_MAX; - break; - case var_integer: - { - unsigned int val; - if (arg == NULL) - error_no_arg ("integer to set it to."); - val = parse_and_eval_address (arg); - if (val == 0) - *(int *) c->var = INT_MAX; - else if (val >= INT_MAX) - error ("integer %u out of range", val); - else - *(int *) c->var = val; - break; - } - case var_zinteger: - if (arg == NULL) - error_no_arg ("integer to set it to."); - *(int *) c->var = parse_and_eval_address (arg); - break; - default: - error ("gdb internal error: bad var_type in do_setshow_command"); - } - } - else if (c->type == show_cmd) - { - /* Print doc minus "show" at start. */ - print_doc_line (gdb_stdout, c->doc + 5); - - fputs_filtered (" is ", gdb_stdout); - wrap_here (" "); - switch (c->var_type) - { - case var_string: - { - unsigned char *p; - fputs_filtered ("\"", gdb_stdout); - for (p = *(unsigned char **) c->var; *p != '\0'; p++) - gdb_printchar (*p, gdb_stdout, '"'); - fputs_filtered ("\"", gdb_stdout); - } - break; - case var_string_noescape: - case var_filename: - fputs_filtered ("\"", gdb_stdout); - fputs_filtered (*(char **) c->var, gdb_stdout); - fputs_filtered ("\"", gdb_stdout); - break; - case var_boolean: - fputs_filtered (*(int *) c->var ? "on" : "off", gdb_stdout); - break; - case var_uinteger: - if (*(unsigned int *) c->var == UINT_MAX) { - fputs_filtered ("unlimited", gdb_stdout); - break; - } - /* else fall through */ - case var_zinteger: - fprintf_filtered (gdb_stdout, "%u", *(unsigned int *) c->var); - break; - case var_integer: - if (*(int *) c->var == INT_MAX) - { - fputs_filtered ("unlimited", gdb_stdout); - } - else - fprintf_filtered (gdb_stdout, "%d", *(int *) c->var); - break; - - default: - error ("gdb internal error: bad var_type in do_setshow_command"); - } - fputs_filtered (".\n", gdb_stdout); - } - else - error ("gdb internal error: bad cmd_type in do_setshow_command"); - (*c->function.sfunc) (NULL, from_tty, c); -} - -/* Show all the settings in a list of show commands. */ - -void -cmd_show_list (list, from_tty, prefix) - struct cmd_list_element *list; - int from_tty; - char *prefix; -{ - for (; list != NULL; list = list->next) { - /* If we find a prefix, run its list, prefixing our output by its - prefix (with "show " skipped). */ - if (list->prefixlist && !list->abbrev_flag) - cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5); - if (list->type == show_cmd) - { - fputs_filtered (prefix, gdb_stdout); - fputs_filtered (list->name, gdb_stdout); - fputs_filtered (": ", gdb_stdout); - do_setshow_command ((char *)NULL, from_tty, list); - } - } -} - -/* ARGSUSED */ -static void -shell_escape (arg, from_tty) - char *arg; - int from_tty; -{ -#ifdef CANT_FORK - /* FIXME: what about errors (I don't know how GO32 system() handles - them)? */ - system (arg); -#else /* Can fork. */ - int rc, status, pid; - char *p, *user_shell; - - if ((user_shell = (char *) getenv ("SHELL")) == NULL) - user_shell = "/bin/sh"; - - /* Get the name of the shell for arg0 */ - if ((p = strrchr (user_shell, '/')) == NULL) - p = user_shell; - else - p++; /* Get past '/' */ - - if ((pid = fork()) == 0) - { - if (!arg) - execl (user_shell, p, 0); - else - execl (user_shell, p, "-c", arg, 0); - - fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell, - safe_strerror (errno)); - gdb_flush (gdb_stderr); - _exit (0177); - } - - if (pid != -1) - while ((rc = wait (&status)) != pid && rc != -1) - ; - else - error ("Fork failed"); -#endif /* Can fork. */ -} - -static void -make_command (arg, from_tty) - char *arg; - int from_tty; -{ - char *p; - - if (arg == 0) - p = "make"; - else - { - p = xmalloc (sizeof("make ") + strlen(arg)); - strcpy (p, "make "); - strcpy (p + sizeof("make ")-1, arg); - } - - shell_escape (p, from_tty); -} - -static void -show_user_1 (c, stream) - struct cmd_list_element *c; - GDB_FILE *stream; -{ - register struct command_line *cmdlines; - - cmdlines = c->user_commands; - if (!cmdlines) - return; - fputs_filtered ("User command ", stream); - fputs_filtered (c->name, stream); - fputs_filtered (":\n", stream); - while (cmdlines) - { - fputs_filtered (cmdlines->line, stream); - fputs_filtered ("\n", stream); - cmdlines = cmdlines->next; - } - fputs_filtered ("\n", stream); -} - -/* ARGSUSED */ -static void -show_user (args, from_tty) - char *args; - int from_tty; -{ - struct cmd_list_element *c; - extern struct cmd_list_element *cmdlist; - - if (args) - { - c = lookup_cmd (&args, cmdlist, "", 0, 1); - if (c->class != class_user) - error ("Not a user command."); - show_user_1 (c, gdb_stdout); - } - else - { - for (c = cmdlist; c; c = c->next) - { - if (c->class == class_user) - show_user_1 (c, gdb_stdout); - } - } -} - -void -_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."); - 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, - "Show definitions of user defined commands.\n\ -Argument is the name of the user defined command.\n\ -With no argument, show definitions of all user defined commands.", &showlist); -} diff --git a/gnu/usr.bin/gdb/gdb/command.h b/gnu/usr.bin/gdb/gdb/command.h deleted file mode 100644 index 360d78a..0000000 --- a/gnu/usr.bin/gdb/gdb/command.h +++ /dev/null @@ -1,246 +0,0 @@ -/* Header file for command-reading library command.c. - Copyright (C) 1986, 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 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 (COMMAND_H) -#define COMMAND_H 1 - -/* Not a set/show command. Note that some commands which begin with - "set" or "show" might be in this category, if their syntax does - not fall into one of the following categories. */ -typedef enum cmd_types { - not_set_cmd, - set_cmd, - show_cmd -} cmd_types; - -/* Types of "set" or "show" command. */ -typedef enum var_types { - /* "on" or "off". *VAR is an integer which is nonzero for on, - zero for off. */ - var_boolean, - /* Unsigned Integer. *VAR is an unsigned int. The user can type 0 - to mean "unlimited", which is stored in *VAR as UINT_MAX. */ - var_uinteger, - - /* Like var_uinteger but signed. *VAR is an int. The user can type 0 - to mean "unlimited", which is stored in *VAR as INT_MAX. */ - var_integer, - - /* String which the user enters with escapes (e.g. the user types \n and - it is a real newline in the stored string). - *VAR is a malloc'd string, or NULL if the string is empty. */ - var_string, - /* String which stores what the user types verbatim. - *VAR is a malloc'd string, or NULL if the string is empty. */ - var_string_noescape, - /* String which stores a filename. - *VAR is a malloc'd string, or NULL if the string is empty. */ - var_filename, - /* ZeroableInteger. *VAR is an int. Like Unsigned Integer except - that zero really means zero. */ - var_zinteger -} var_types; - -/* This structure records one command'd definition. */ - -struct cmd_list_element - { - /* Points to next command in this list. */ - struct cmd_list_element *next; - - /* Name of this command. */ - char *name; - - /* Command class; class values are chosen by application program. */ - enum command_class class; - - /* Function definition of this command. - NO_FUNCTION for command class names and for help topics that - are not really commands. */ - union - { - /* If type is not_set_cmd, call it like this: */ - void (*cfunc) PARAMS ((char *args, int from_tty)); - - /* If type is cmd_set or show_cmd, first set the variables, and - then call this. */ - void (*sfunc) PARAMS ((char *args, int from_tty, - struct cmd_list_element *c)); - } function; -# define NO_FUNCTION ((void (*) PARAMS((char *args, int from_tty))) 0) - - /* Documentation of this command (or help topic). - First line is brief documentation; remaining lines form, with it, - the full documentation. First line should end with a period. - Entire string should also end with a period, not a newline. */ - char *doc; - - /* Hook for another command to be executed before this command. */ - struct cmd_list_element *hook; - - /* Nonzero identifies a prefix command. For them, the address - of the variable containing the list of subcommands. */ - struct cmd_list_element **prefixlist; - - /* For prefix commands only: - String containing prefix commands to get here: this one - plus any others needed to get to it. Should end in a space. - It is used before the word "command" in describing the - commands reached through this prefix. */ - char *prefixname; - - /* For prefix commands only: - nonzero means do not get an error if subcommand is not - recognized; call the prefix's own function in that case. */ - char allow_unknown; - - /* Nonzero says this is an abbreviation, and should not - be mentioned in lists of commands. - This allows "br" to complete to "break", which it - otherwise wouldn't. */ - char abbrev_flag; - - /* Completion routine for this command. TEXT is the text beyond - what was matched for the command itself (leading whitespace is - skipped). It stops where we are supposed to stop completing - (rl_point) and is '\0' terminated. - - Return value is a malloc'd vector of pointers to possible completions - terminated with NULL. If there are no completions, returning a pointer - to a NULL would work but returning NULL itself is also valid. - WORD points in the same buffer as TEXT, and completions should be - returned relative to this position. For example, suppose TEXT is "foo" - and we want to complete to "foobar". If WORD is "oo", return - "oobar"; if WORD is "baz/foo", return "baz/foobar". */ - char ** (*completer) PARAMS ((char *text, char *word)); - - /* Type of "set" or "show" command (or SET_NOT_SET if not "set" - or "show"). */ - cmd_types type; - - /* Pointer to variable affected by "set" and "show". Doesn't matter - if type is not_set. */ - char *var; - - /* What kind of variable is *VAR? */ - var_types var_type; - - /* Pointer to command strings of user-defined commands */ - struct command_line *user_commands; - - /* Pointer to command that is hooked by this one, - so the hook can be removed when this one is deleted. */ - struct cmd_list_element *hookee; - - /* Pointer to command that is aliased by this one, so the - aliased command can be located in case it has been hooked. */ - struct cmd_list_element *cmd_pointer; - }; - -/* Forward-declarations of the entry-points of command.c. */ - -extern struct cmd_list_element * -add_cmd PARAMS ((char *, enum command_class, void (*fun) (char *, int), - char *, struct cmd_list_element **)); - -extern struct cmd_list_element * -add_alias_cmd PARAMS ((char *, char *, enum command_class, int, - struct cmd_list_element **)); - -extern struct cmd_list_element * -add_prefix_cmd PARAMS ((char *, enum command_class, void (*fun) (char *, int), - char *, struct cmd_list_element **, char *, int, - struct cmd_list_element **)); - -extern struct cmd_list_element * -add_abbrev_prefix_cmd PARAMS ((char *, enum command_class, - void (*fun) (char *, int), char *, - struct cmd_list_element **, char *, int, - struct cmd_list_element **)); - -extern struct cmd_list_element * -lookup_cmd PARAMS ((char **, struct cmd_list_element *, char *, int, int)); - -extern struct cmd_list_element * -lookup_cmd_1 PARAMS ((char **, struct cmd_list_element *, - struct cmd_list_element **, int)); - -extern void -add_com PARAMS ((char *, enum command_class, void (*fun)(char *, int), - char *)); - -extern void -add_com_alias PARAMS ((char *, char *, enum command_class, int)); - -extern void -add_info PARAMS ((char *, void (*fun) (char *, int), char *)); - -extern void -add_info_alias PARAMS ((char *, char *, int)); - -extern char **complete_on_cmdlist PARAMS ((struct cmd_list_element *, - char *, char *)); - -extern void -delete_cmd PARAMS ((char *, struct cmd_list_element **)); - -extern void -help_cmd PARAMS ((char *, GDB_FILE *)); - -extern void -help_list PARAMS ((struct cmd_list_element *, char *, enum command_class, - GDB_FILE *)); - -extern void -help_cmd_list PARAMS ((struct cmd_list_element *, enum command_class, char *, - int, GDB_FILE *)); - -extern struct cmd_list_element * -add_set_cmd PARAMS ((char *, enum command_class, var_types, char *, char *, - struct cmd_list_element **)); - -extern struct cmd_list_element * -add_show_from_set PARAMS ((struct cmd_list_element *, - struct cmd_list_element **)); - -/* Do a "set" or "show" command. ARG is NULL if no argument, or the text - of the argument, and FROM_TTY is nonzero if this command is being entered - directly by the user (i.e. these are just like any other - command). C is the command list element for the command. */ - -extern void -do_setshow_command PARAMS ((char *, int, struct cmd_list_element *)); - -/* Do a "show" command for each thing on a command list. */ - -extern void -cmd_show_list PARAMS ((struct cmd_list_element *, int, char *)); - -extern void -error_no_arg PARAMS ((char *)); - -extern void -dont_repeat PARAMS ((void)); - -/* Used to mark commands that don't do anything. If we just leave the - function field NULL, the command is interpreted as a help topic, or - as a class of commands. */ - -extern void -not_just_help_class_command PARAMS ((char *, int)); - -#endif /* !defined (COMMAND_H) */ diff --git a/gnu/usr.bin/gdb/gdb/compat_que.c b/gnu/usr.bin/gdb/gdb/compat_que.c deleted file mode 100644 index df185a2..0000000 --- a/gnu/usr.bin/gdb/gdb/compat_que.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 1987, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)compat_que.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -/* - * insque/remque -- vax insque instruction - * - * NOTE: this implementation is non-atomic!! - */ - -struct vaxque { /* queue format expected by VAX queue instructions */ - struct vaxque *vq_next; - struct vaxque *vq_prev; -}; - -insque(e, prev) - register struct vaxque *e, *prev; -{ - e->vq_prev = prev; - e->vq_next = prev->vq_next; - prev->vq_next->vq_prev = e; - prev->vq_next = e; -} - -remque(e) - register struct vaxque *e; -{ - e->vq_prev->vq_next = e->vq_next; - e->vq_next->vq_prev = e->vq_prev; -} diff --git a/gnu/usr.bin/gdb/gdb/complaints.c b/gnu/usr.bin/gdb/gdb/complaints.c deleted file mode 100644 index 7ba7b18..0000000 --- a/gnu/usr.bin/gdb/gdb/complaints.c +++ /dev/null @@ -1,158 +0,0 @@ -/* Support for complaint handling during symbol reading in GDB. - Copyright (C) 1990, 1991, 1992 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 "defs.h" -#include "complaints.h" -#include "gdbcmd.h" -#include - -/* Structure to manage complaints about symbol file contents. */ - -struct complaint complaint_root[1] = { - { - (char *) NULL, /* Complaint message */ - 0, /* Complaint counter */ - complaint_root /* Next complaint. */ - } -}; - -/* How many complaints about a particular thing should be printed before - we stop whining about it? Default is no whining at all, since so many - systems have ill-constructed symbol files. */ - -static unsigned int stop_whining = 0; - -/* Should each complaint be self explanatory, or should we assume that - a series of complaints is being produced? - case 0: self explanatory message. - case 1: First message of a series that must start off with explanation. - case 2: Subsequent message, when user already knows we are reading - symbols and we can just state our piece. */ - -static int complaint_series = 0; - -/* External variables and functions referenced. */ - -extern int info_verbose; - - -/* Functions to handle complaints during symbol reading. */ - -/* Print a complaint about the input symbols, and link the complaint block - into a chain for later handling. */ - -/* VARARGS */ -void -complain (va_alist) - va_dcl -{ - va_list args; - struct complaint *complaint; - - va_start (args); - complaint = va_arg (args, struct complaint *); - complaint -> counter++; - if (complaint -> next == NULL) - { - complaint -> next = complaint_root -> next; - complaint_root -> next = complaint; - } - if (complaint -> counter > stop_whining) - { - return; - } - wrap_here (""); - - switch (complaint_series + (info_verbose << 1)) - { - - /* Isolated messages, must be self-explanatory. */ - case 0: - begin_line (); - puts_filtered ("During symbol reading, "); - wrap_here (""); - vprintf_filtered (complaint -> message, args); - puts_filtered (".\n"); - break; - - /* First of a series, without `set verbose'. */ - case 1: - begin_line (); - puts_filtered ("During symbol reading..."); - vprintf_filtered (complaint -> message, args); - puts_filtered ("..."); - wrap_here (""); - complaint_series++; - break; - - /* Subsequent messages of a series, or messages under `set verbose'. - (We'll already have produced a "Reading in symbols for XXX..." - message and will clean up at the end with a newline.) */ - default: - vprintf_filtered (complaint -> message, args); - puts_filtered ("..."); - wrap_here (""); - } - /* If GDB dumps core, we'd like to see the complaints first. Presumably - GDB will not be sending so many complaints that this becomes a - performance hog. */ - gdb_flush (gdb_stdout); - va_end (args); -} - -/* Clear out all complaint counters that have ever been incremented. - If sym_reading is 1, be less verbose about successive complaints, - since the messages are appearing all together during a command that - reads symbols (rather than scattered around as psymtabs get fleshed - out into symtabs at random times). If noisy is 1, we are in a - noisy symbol reading command, and our caller will print enough - context for the user to figure it out. */ - -void -clear_complaints (sym_reading, noisy) - int sym_reading; - int noisy; -{ - struct complaint *p; - - for (p = complaint_root -> next; p != complaint_root; p = p -> next) - { - p -> counter = 0; - } - - if (!sym_reading && !noisy && complaint_series > 1) - { - /* Terminate previous series, since caller won't. */ - puts_filtered ("\n"); - } - - complaint_series = sym_reading ? 1 + noisy : 0; -} - -void -_initialize_complaints () -{ - add_show_from_set - (add_set_cmd ("complaints", class_support, var_zinteger, - (char *) &stop_whining, - "Set max number of complaints about incorrect symbols.", - &setlist), - &showlist); - -} diff --git a/gnu/usr.bin/gdb/gdb/complaints.h b/gnu/usr.bin/gdb/gdb/complaints.h deleted file mode 100644 index ea10cab..0000000 --- a/gnu/usr.bin/gdb/gdb/complaints.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Definitions for complaint handling during symbol reading in GDB. - Copyright (C) 1990, 1991, 1992 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. */ - - -/* Support for complaining about things in the symbol file that aren't - catastrophic. - - Each such thing gets a counter. The first time we have the problem, - during a symbol read, we report it. At the end of symbol reading, - if verbose, we report how many of each problem we had. */ - -struct complaint -{ - char *message; - unsigned counter; - struct complaint *next; -}; - -/* Root of the chain of complaints that have at some point been issued. - This is used to reset the counters, and/or report the total counts. */ - -extern struct complaint complaint_root[1]; - -/* Functions that handle complaints. (in complaints.c) */ - -extern void -complain (); - -extern void -clear_complaints PARAMS ((int, int)); diff --git a/gnu/usr.bin/gdb/gdb/config.h b/gnu/usr.bin/gdb/gdb/config.h new file mode 100644 index 0000000..29f0a3c --- /dev/null +++ b/gnu/usr.bin/gdb/gdb/config.h @@ -0,0 +1,91 @@ +/* config.h. Generated automatically by configure. */ +/* config.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define if the `long double' type works. */ +#define HAVE_LONG_DOUBLE 1 + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define if on MINIX. */ +/* #undef _MINIX */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if fpregset_t type is available. */ +/* #undef HAVE_FPREGSET_T */ + +/* Define if gregset_t type is available. */ +/* #undef HAVE_GREGSET_T */ + +/* Define if the "%Lg" format works to print long doubles. */ +#define PRINTF_HAS_LONG_DOUBLE 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the sbrk function. */ +#define HAVE_SBRK 1 + +/* Define if you have the setpgid function. */ +#define HAVE_SETPGID 1 + +/* Define if you have the valloc function. */ +#define HAVE_VALLOC 1 + +/* Define if you have the header file. */ +/* #undef HAVE_ENDIAN_H */ + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINK_H 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +#define HAVE_SGTTY_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PROCFS_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_TERMIO_H */ + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the dl library (-ldl). */ +/* #undef HAVE_LIBDL */ diff --git a/gnu/usr.bin/gdb/gdb/copying.c b/gnu/usr.bin/gdb/gdb/copying.c deleted file mode 100644 index ffc884a..0000000 --- a/gnu/usr.bin/gdb/gdb/copying.c +++ /dev/null @@ -1,327 +0,0 @@ -/* ==> Do not modify this file!! It is created automatically - by copying.awk. Modify copying.awk instead. <== */ - -#include "defs.h" -#include "command.h" -#include "gdbcmd.h" - -static void -show_copying_command PARAMS ((char *, int)); - -static void -show_warranty_command PARAMS ((char *, int)); - -extern int immediate_quit; -static void -show_copying_command (ignore, from_tty) - char *ignore; - int from_tty; -{ - immediate_quit++; - printf_filtered (" GNU GENERAL PUBLIC LICENSE\n"); - 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 (" 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"); - printf_filtered (" Preamble\n"); - printf_filtered ("\n"); - printf_filtered (" The licenses for most software are designed to take away your\n"); - printf_filtered ("freedom to share and change it. By contrast, the GNU General Public\n"); - printf_filtered ("License is intended to guarantee your freedom to share and change free\n"); - printf_filtered ("software--to make sure the software is free for all its users. This\n"); - printf_filtered ("General Public License applies to most of the Free Software\n"); - printf_filtered ("Foundation's software and to any other program whose authors commit to\n"); - printf_filtered ("using it. (Some other Free Software Foundation software is covered by\n"); - printf_filtered ("the GNU Library General Public License instead.) You can apply it to\n"); - printf_filtered ("your programs, too.\n"); - printf_filtered ("\n"); - printf_filtered (" When we speak of free software, we are referring to freedom, not\n"); - printf_filtered ("price. Our General Public Licenses are designed to make sure that you\n"); - printf_filtered ("have the freedom to distribute copies of free software (and charge for\n"); - printf_filtered ("this service if you wish), that you receive source code or can get it\n"); - printf_filtered ("if you want it, that you can change the software or use pieces of it\n"); - printf_filtered ("in new free programs; and that you know you can do these things.\n"); - printf_filtered ("\n"); - printf_filtered (" To protect your rights, we need to make restrictions that forbid\n"); - printf_filtered ("anyone to deny you these rights or to ask you to surrender the rights.\n"); - printf_filtered ("These restrictions translate to certain responsibilities for you if you\n"); - printf_filtered ("distribute copies of the software, or if you modify it.\n"); - printf_filtered ("\n"); - printf_filtered (" For example, if you distribute copies of such a program, whether\n"); - printf_filtered ("gratis or for a fee, you must give the recipients all the rights that\n"); - printf_filtered ("you have. You must make sure that they, too, receive or can get the\n"); - printf_filtered ("source code. And you must show them these terms so they know their\n"); - printf_filtered ("rights.\n"); - printf_filtered ("\n"); - printf_filtered (" We protect your rights with two steps: (1) copyright the software, and\n"); - printf_filtered ("(2) offer you this license which gives you legal permission to copy,\n"); - printf_filtered ("distribute and/or modify the software.\n"); - printf_filtered ("\n"); - printf_filtered (" Also, for each author's protection and ours, we want to make certain\n"); - printf_filtered ("that everyone understands that there is no warranty for this free\n"); - printf_filtered ("software. If the software is modified by someone else and passed on, we\n"); - printf_filtered ("want its recipients to know that what they have is not the original, so\n"); - printf_filtered ("that any problems introduced by others will not reflect on the original\n"); - printf_filtered ("authors' reputations.\n"); - printf_filtered ("\n"); - printf_filtered (" Finally, any free program is threatened constantly by software\n"); - printf_filtered ("patents. We wish to avoid the danger that redistributors of a free\n"); - printf_filtered ("program will individually obtain patent licenses, in effect making the\n"); - printf_filtered ("program proprietary. To prevent this, we have made it clear that any\n"); - printf_filtered ("patent must be licensed for everyone's free use or not licensed at all.\n"); - printf_filtered ("\n"); - printf_filtered (" The precise terms and conditions for copying, distribution and\n"); - printf_filtered ("modification follow.\n"); - printf_filtered ("\n"); - printf_filtered (" GNU GENERAL PUBLIC LICENSE\n"); - printf_filtered (" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n"); - printf_filtered ("\n"); - printf_filtered (" 0. This License applies to any program or other work which contains\n"); - printf_filtered ("a notice placed by the copyright holder saying it may be distributed\n"); - printf_filtered ("under the terms of this General Public License. The \"Program\", below,\n"); - printf_filtered ("refers to any such program or work, and a \"work based on the Program\"\n"); - printf_filtered ("means either the Program or any derivative work under copyright law:\n"); - printf_filtered ("that is to say, a work containing the Program or a portion of it,\n"); - printf_filtered ("either verbatim or with modifications and/or translated into another\n"); - printf_filtered ("language. (Hereinafter, translation is included without limitation in\n"); - printf_filtered ("the term \"modification\".) Each licensee is addressed as \"you\".\n"); - printf_filtered ("\n"); - printf_filtered ("Activities other than copying, distribution and modification are not\n"); - printf_filtered ("covered by this License; they are outside its scope. The act of\n"); - printf_filtered ("running the Program is not restricted, and the output from the Program\n"); - printf_filtered ("is covered only if its contents constitute a work based on the\n"); - printf_filtered ("Program (independent of having been made by running the Program).\n"); - printf_filtered ("Whether that is true depends on what the Program does.\n"); - printf_filtered ("\n"); - printf_filtered (" 1. You may copy and distribute verbatim copies of the Program's\n"); - printf_filtered ("source code as you receive it, in any medium, provided that you\n"); - printf_filtered ("conspicuously and appropriately publish on each copy an appropriate\n"); - printf_filtered ("copyright notice and disclaimer of warranty; keep intact all the\n"); - printf_filtered ("notices that refer to this License and to the absence of any warranty;\n"); - printf_filtered ("and give any other recipients of the Program a copy of this License\n"); - printf_filtered ("along with the Program.\n"); - printf_filtered ("\n"); - printf_filtered ("You may charge a fee for the physical act of transferring a copy, and\n"); - printf_filtered ("you may at your option offer warranty protection in exchange for a fee.\n"); - printf_filtered ("\n"); - printf_filtered (" 2. You may modify your copy or copies of the Program or any portion\n"); - printf_filtered ("of it, thus forming a work based on the Program, and copy and\n"); - printf_filtered ("distribute such modifications or work under the terms of Section 1\n"); - printf_filtered ("above, provided that you also meet all of these conditions:\n"); - printf_filtered ("\n"); - printf_filtered (" a) You must cause the modified files to carry prominent notices\n"); - printf_filtered (" stating that you changed the files and the date of any change.\n"); - printf_filtered ("\n"); - printf_filtered (" b) You must cause any work that you distribute or publish, that in\n"); - printf_filtered (" whole or in part contains or is derived from the Program or any\n"); - printf_filtered (" part thereof, to be licensed as a whole at no charge to all third\n"); - printf_filtered (" parties under the terms of this License.\n"); - printf_filtered ("\n"); - printf_filtered (" c) If the modified program normally reads commands interactively\n"); - printf_filtered (" when run, you must cause it, when started running for such\n"); - printf_filtered (" interactive use in the most ordinary way, to print or display an\n"); - printf_filtered (" announcement including an appropriate copyright notice and a\n"); - printf_filtered (" notice that there is no warranty (or else, saying that you provide\n"); - printf_filtered (" a warranty) and that users may redistribute the program under\n"); - printf_filtered (" these conditions, and telling the user how to view a copy of this\n"); - printf_filtered (" License. (Exception: if the Program itself is interactive but\n"); - printf_filtered (" does not normally print such an announcement, your work based on\n"); - printf_filtered (" the Program is not required to print an announcement.)\n"); - printf_filtered ("\n"); - printf_filtered ("These requirements apply to the modified work as a whole. If\n"); - printf_filtered ("identifiable sections of that work are not derived from the Program,\n"); - printf_filtered ("and can be reasonably considered independent and separate works in\n"); - printf_filtered ("themselves, then this License, and its terms, do not apply to those\n"); - printf_filtered ("sections when you distribute them as separate works. But when you\n"); - printf_filtered ("distribute the same sections as part of a whole which is a work based\n"); - printf_filtered ("on the Program, the distribution of the whole must be on the terms of\n"); - printf_filtered ("this License, whose permissions for other licensees extend to the\n"); - printf_filtered ("entire whole, and thus to each and every part regardless of who wrote it.\n"); - printf_filtered ("\n"); - printf_filtered ("Thus, it is not the intent of this section to claim rights or contest\n"); - printf_filtered ("your rights to work written entirely by you; rather, the intent is to\n"); - printf_filtered ("exercise the right to control the distribution of derivative or\n"); - printf_filtered ("collective works based on the Program.\n"); - printf_filtered ("\n"); - printf_filtered ("In addition, mere aggregation of another work not based on the Program\n"); - printf_filtered ("with the Program (or with a work based on the Program) on a volume of\n"); - printf_filtered ("a storage or distribution medium does not bring the other work under\n"); - printf_filtered ("the scope of this License.\n"); - printf_filtered ("\n"); - printf_filtered (" 3. You may copy and distribute the Program (or a work based on it,\n"); - printf_filtered ("under Section 2) in object code or executable form under the terms of\n"); - printf_filtered ("Sections 1 and 2 above provided that you also do one of the following:\n"); - printf_filtered ("\n"); - printf_filtered (" a) Accompany it with the complete corresponding machine-readable\n"); - printf_filtered (" source code, which must be distributed under the terms of Sections\n"); - printf_filtered (" 1 and 2 above on a medium customarily used for software interchange; or,\n"); - printf_filtered ("\n"); - printf_filtered (" b) Accompany it with a written offer, valid for at least three\n"); - printf_filtered (" years, to give any third party, for a charge no more than your\n"); - printf_filtered (" cost of physically performing source distribution, a complete\n"); - printf_filtered (" machine-readable copy of the corresponding source code, to be\n"); - printf_filtered (" distributed under the terms of Sections 1 and 2 above on a medium\n"); - printf_filtered (" customarily used for software interchange; or,\n"); - printf_filtered ("\n"); - printf_filtered (" c) Accompany it with the information you received as to the offer\n"); - printf_filtered (" to distribute corresponding source code. (This alternative is\n"); - printf_filtered (" allowed only for noncommercial distribution and only if you\n"); - printf_filtered (" received the program in object code or executable form with such\n"); - printf_filtered (" an offer, in accord with Subsection b above.)\n"); - printf_filtered ("\n"); - printf_filtered ("The source code for a work means the preferred form of the work for\n"); - printf_filtered ("making modifications to it. For an executable work, complete source\n"); - printf_filtered ("code means all the source code for all modules it contains, plus any\n"); - printf_filtered ("associated interface definition files, plus the scripts used to\n"); - printf_filtered ("control compilation and installation of the executable. However, as a\n"); - printf_filtered ("special exception, the source code distributed need not include\n"); - printf_filtered ("anything that is normally distributed (in either source or binary\n"); - printf_filtered ("form) with the major components (compiler, kernel, and so on) of the\n"); - printf_filtered ("operating system on which the executable runs, unless that component\n"); - printf_filtered ("itself accompanies the executable.\n"); - printf_filtered ("\n"); - printf_filtered ("If distribution of executable or object code is made by offering\n"); - printf_filtered ("access to copy from a designated place, then offering equivalent\n"); - printf_filtered ("access to copy the source code from the same place counts as\n"); - printf_filtered ("distribution of the source code, even though third parties are not\n"); - printf_filtered ("compelled to copy the source along with the object code.\n"); - printf_filtered ("\n"); - printf_filtered (" 4. You may not copy, modify, sublicense, or distribute the Program\n"); - printf_filtered ("except as expressly provided under this License. Any attempt\n"); - printf_filtered ("otherwise to copy, modify, sublicense or distribute the Program is\n"); - printf_filtered ("void, and will automatically terminate your rights under this License.\n"); - printf_filtered ("However, parties who have received copies, or rights, from you under\n"); - printf_filtered ("this License will not have their licenses terminated so long as such\n"); - printf_filtered ("parties remain in full compliance.\n"); - printf_filtered ("\n"); - printf_filtered (" 5. You are not required to accept this License, since you have not\n"); - printf_filtered ("signed it. However, nothing else grants you permission to modify or\n"); - printf_filtered ("distribute the Program or its derivative works. These actions are\n"); - printf_filtered ("prohibited by law if you do not accept this License. Therefore, by\n"); - printf_filtered ("modifying or distributing the Program (or any work based on the\n"); - printf_filtered ("Program), you indicate your acceptance of this License to do so, and\n"); - printf_filtered ("all its terms and conditions for copying, distributing or modifying\n"); - printf_filtered ("the Program or works based on it.\n"); - printf_filtered ("\n"); - printf_filtered (" 6. Each time you redistribute the Program (or any work based on the\n"); - printf_filtered ("Program), the recipient automatically receives a license from the\n"); - printf_filtered ("original licensor to copy, distribute or modify the Program subject to\n"); - printf_filtered ("these terms and conditions. You may not impose any further\n"); - printf_filtered ("restrictions on the recipients' exercise of the rights granted herein.\n"); - printf_filtered ("You are not responsible for enforcing compliance by third parties to\n"); - printf_filtered ("this License.\n"); - printf_filtered ("\n"); - printf_filtered (" 7. If, as a consequence of a court judgment or allegation of patent\n"); - printf_filtered ("infringement or for any other reason (not limited to patent issues),\n"); - printf_filtered ("conditions are imposed on you (whether by court order, agreement or\n"); - printf_filtered ("otherwise) that contradict the conditions of this License, they do not\n"); - printf_filtered ("excuse you from the conditions of this License. If you cannot\n"); - printf_filtered ("distribute so as to satisfy simultaneously your obligations under this\n"); - printf_filtered ("License and any other pertinent obligations, then as a consequence you\n"); - printf_filtered ("may not distribute the Program at all. For example, if a patent\n"); - printf_filtered ("license would not permit royalty-free redistribution of the Program by\n"); - printf_filtered ("all those who receive copies directly or indirectly through you, then\n"); - printf_filtered ("the only way you could satisfy both it and this License would be to\n"); - printf_filtered ("refrain entirely from distribution of the Program.\n"); - printf_filtered ("\n"); - printf_filtered ("If any portion of this section is held invalid or unenforceable under\n"); - printf_filtered ("any particular circumstance, the balance of the section is intended to\n"); - printf_filtered ("apply and the section as a whole is intended to apply in other\n"); - printf_filtered ("circumstances.\n"); - printf_filtered ("\n"); - printf_filtered ("It is not the purpose of this section to induce you to infringe any\n"); - printf_filtered ("patents or other property right claims or to contest validity of any\n"); - printf_filtered ("such claims; this section has the sole purpose of protecting the\n"); - printf_filtered ("integrity of the free software distribution system, which is\n"); - printf_filtered ("implemented by public license practices. Many people have made\n"); - printf_filtered ("generous contributions to the wide range of software distributed\n"); - printf_filtered ("through that system in reliance on consistent application of that\n"); - printf_filtered ("system; it is up to the author/donor to decide if he or she is willing\n"); - printf_filtered ("to distribute software through any other system and a licensee cannot\n"); - printf_filtered ("impose that choice.\n"); - printf_filtered ("\n"); - printf_filtered ("This section is intended to make thoroughly clear what is believed to\n"); - printf_filtered ("be a consequence of the rest of this License.\n"); - printf_filtered ("\n"); - printf_filtered (" 8. If the distribution and/or use of the Program is restricted in\n"); - printf_filtered ("certain countries either by patents or by copyrighted interfaces, the\n"); - printf_filtered ("original copyright holder who places the Program under this License\n"); - printf_filtered ("may add an explicit geographical distribution limitation excluding\n"); - printf_filtered ("those countries, so that distribution is permitted only in or among\n"); - printf_filtered ("countries not thus excluded. In such case, this License incorporates\n"); - printf_filtered ("the limitation as if written in the body of this License.\n"); - printf_filtered ("\n"); - printf_filtered (" 9. The Free Software Foundation may publish revised and/or new versions\n"); - printf_filtered ("of the General Public License from time to time. Such new versions will\n"); - printf_filtered ("be similar in spirit to the present version, but may differ in detail to\n"); - printf_filtered ("address new problems or concerns.\n"); - printf_filtered ("\n"); - printf_filtered ("Each version is given a distinguishing version number. If the Program\n"); - printf_filtered ("specifies a version number of this License which applies to it and \"any\n"); - printf_filtered ("later version\", you have the option of following the terms and conditions\n"); - printf_filtered ("either of that version or of any later version published by the Free\n"); - printf_filtered ("Software Foundation. If the Program does not specify a version number of\n"); - printf_filtered ("this License, you may choose any version ever published by the Free Software\n"); - printf_filtered ("Foundation.\n"); - printf_filtered ("\n"); - printf_filtered (" 10. If you wish to incorporate parts of the Program into other free\n"); - printf_filtered ("programs whose distribution conditions are different, write to the author\n"); - printf_filtered ("to ask for permission. For software which is copyrighted by the Free\n"); - printf_filtered ("Software Foundation, write to the Free Software Foundation; we sometimes\n"); - printf_filtered ("make exceptions for this. Our decision will be guided by the two goals\n"); - printf_filtered ("of preserving the free status of all derivatives of our free software and\n"); - printf_filtered ("of promoting the sharing and reuse of software generally.\n"); - printf_filtered ("\n"); - immediate_quit--; -} - -static void -show_warranty_command (ignore, from_tty) - char *ignore; - int from_tty; -{ - immediate_quit++; - printf_filtered (" NO WARRANTY\n"); - printf_filtered ("\n"); - printf_filtered (" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"); - printf_filtered ("FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n"); - printf_filtered ("OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"); - printf_filtered ("PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"); - printf_filtered ("OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"); - printf_filtered ("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n"); - printf_filtered ("TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n"); - printf_filtered ("PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"); - printf_filtered ("REPAIR OR CORRECTION.\n"); - printf_filtered ("\n"); - printf_filtered (" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"); - printf_filtered ("WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"); - printf_filtered ("REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"); - printf_filtered ("INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"); - printf_filtered ("OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"); - printf_filtered ("TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"); - printf_filtered ("YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"); - printf_filtered ("PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"); - printf_filtered ("POSSIBILITY OF SUCH DAMAGES.\n"); - printf_filtered ("\n"); - immediate_quit--; -} - -void -_initialize_copying () -{ - add_cmd ("copying", no_class, show_copying_command, - "Conditions for redistributing copies of GDB.", - &showlist); - add_cmd ("warranty", no_class, show_warranty_command, - "Various kinds of warranty you do not have.", - &showlist); - - /* For old-timers, allow "info copying", etc. */ - add_info ("copying", show_copying_command, - "Conditions for redistributing copies of GDB."); - add_info ("warranty", show_warranty_command, - "Various kinds of warranty you do not have."); -} diff --git a/gnu/usr.bin/gdb/gdb/core.c b/gnu/usr.bin/gdb/gdb/core.c deleted file mode 100644 index 974e55c..0000000 --- a/gnu/usr.bin/gdb/gdb/core.c +++ /dev/null @@ -1,339 +0,0 @@ -/* Core dump and executable file functions above target vector, for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include -#include -#include -#include -#include "frame.h" /* required by inferior.h */ -#include "inferior.h" -#include "symtab.h" -#include "command.h" -#include "gdbcmd.h" -#include "bfd.h" -#include "target.h" -#include "gdbcore.h" -#include "dis-asm.h" -#include "language.h" - -extern char registers[]; - -/* Hook for `exec_file_command' command to call. */ - -void (*exec_file_display_hook) PARAMS ((char *)) = NULL; - -/* Binary file diddling handle for the core file. */ - -bfd *core_bfd = NULL; - - -/* Backward compatability with old way of specifying core files. */ - -void -core_file_command (filename, from_tty) - char *filename; - int from_tty; -{ - struct target_ops *t; - - dont_repeat (); /* Either way, seems bogus. */ - - t = find_core_target (); - if (t != NULL) - if (!filename) - (t->to_detach) (filename, from_tty); - else - (t->to_open) (filename, from_tty); - else - error ("GDB can't read core files on this machine."); -} - - -/* Call this to specify the hook for exec_file_command to call back. - This is called from the x-window display code. */ - -void -specify_exec_file_hook (hook) - void (*hook) PARAMS ((char *)); -{ - exec_file_display_hook = hook; -} - -/* The exec file must be closed before running an inferior. - If it is needed again after the inferior dies, it must - be reopened. */ - -void -close_exec_file () -{ -#ifdef FIXME - if (exec_bfd) - bfd_tempclose (exec_bfd); -#endif -} - -void -reopen_exec_file () -{ -#ifdef FIXME - if (exec_bfd) - bfd_reopen (exec_bfd); -#endif -} - -/* If we have both a core file and an exec file, - print a warning if they don't go together. */ - -void -validate_files () -{ - if (exec_bfd && core_bfd) - { - if (!core_file_matches_executable_p (core_bfd, exec_bfd)) - warning ("core file may not match specified executable file."); - else if (bfd_get_mtime(exec_bfd) > bfd_get_mtime(core_bfd)) - warning ("exec file is newer than core file."); - } -} - -/* Return the name of the executable file as a string. - ERR nonzero means get error if there is none specified; - otherwise return 0 in that case. */ - -char * -get_exec_file (err) - int err; -{ - if (exec_bfd) return bfd_get_filename(exec_bfd); - if (!err) return NULL; - - error ("No executable file specified.\n\ -Use the \"file\" or \"exec-file\" command."); - return NULL; -} - - -/* Report a memory error with error(). */ - -void -memory_error (status, memaddr) - int status; - CORE_ADDR memaddr; -{ - if (status == EIO) - { - /* Actually, address between memaddr and memaddr + len - was out of bounds. */ - error_begin (); - printf_filtered ("Cannot access memory at address "); - print_address_numeric (memaddr, 1, gdb_stdout); - printf_filtered (".\n"); - return_to_top_level (RETURN_ERROR); - } - else - { - error_begin (); - printf_filtered ("Error accessing memory address "); - print_address_numeric (memaddr, 1, gdb_stdout); - printf_filtered (": %s.\n", - safe_strerror (status)); - return_to_top_level (RETURN_ERROR); - } -} - -/* Same as target_read_memory, but report an error if can't read. */ -void -read_memory (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - int status; - status = target_read_memory (memaddr, myaddr, len); - if (status != 0) - memory_error (status, memaddr); -} - -/* Like target_read_memory, but slightly different parameters. */ - -int -dis_asm_read_memory (memaddr, myaddr, len, info) - bfd_vma memaddr; - bfd_byte *myaddr; - int len; - disassemble_info *info; -{ - return target_read_memory (memaddr, (char *) myaddr, len); -} - -/* Like memory_error with slightly different parameters. */ -void -dis_asm_memory_error (status, memaddr, info) - int status; - bfd_vma memaddr; - disassemble_info *info; -{ - memory_error (status, memaddr); -} - -/* Like print_address with slightly different parameters. */ -void -dis_asm_print_address (addr, info) - bfd_vma addr; - struct disassemble_info *info; -{ - print_address (addr, info->stream); -} - -/* Same as target_write_memory, but report an error if can't write. */ -void -write_memory (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - int status; - - status = target_write_memory (memaddr, myaddr, len); - if (status != 0) - memory_error (status, memaddr); -} - -/* Read an integer from debugged memory, given address and number of bytes. */ - -LONGEST -read_memory_integer (memaddr, len) - CORE_ADDR memaddr; - int len; -{ - char buf[sizeof (LONGEST)]; - - read_memory (memaddr, buf, len); - return extract_signed_integer (buf, len); -} - -unsigned LONGEST -read_memory_unsigned_integer (memaddr, len) - CORE_ADDR memaddr; - int len; -{ - char buf[sizeof (unsigned LONGEST)]; - - read_memory (memaddr, buf, len); - return extract_unsigned_integer (buf, len); -} - -#if 0 -/* Enable after 4.12. It is not tested. */ - -/* Search code. Targets can just make this their search function, or - if the protocol has a less general search function, they can call this - in the cases it can't handle. */ -void -generic_search (len, data, mask, startaddr, increment, lorange, hirange - addr_found, data_found) - int len; - char *data; - char *mask; - CORE_ADDR startaddr; - int increment; - CORE_ADDR lorange; - CORE_ADDR hirange; - CORE_ADDR *addr_found; - char *data_found; -{ - int i; - CORE_ADDR curaddr = startaddr; - - while (curaddr >= lorange && curaddr < hirange) - { - read_memory (curaddr, data_found, len); - for (i = 0; i < len; ++i) - if ((data_found[i] & mask[i]) != data[i]) - goto try_again; - /* It matches. */ - *addr_found = curaddr; - return; - - try_again: - curaddr += increment; - } - *addr_found = (CORE_ADDR)0; - return; -} -#endif /* 0 */ - -/* The current default bfd target. Points to storage allocated for - gnutarget_string. */ -char *gnutarget; - -/* Same thing, except it is "auto" not NULL for the default case. */ -static char *gnutarget_string; - -static void set_gnutarget_command - PARAMS ((char *, int, struct cmd_list_element *)); - -static void -set_gnutarget_command (ignore, from_tty, c) - char *ignore; - int from_tty; - struct cmd_list_element *c; -{ - if (STREQ (gnutarget_string, "auto")) - gnutarget = NULL; - else - gnutarget = gnutarget_string; -} - -/* Set the gnutarget. */ -void -set_gnutarget (newtarget) - char *newtarget; -{ - if (gnutarget_string != NULL) - free (gnutarget_string); - gnutarget_string = savestring (newtarget, strlen (newtarget)); - set_gnutarget_command (NULL, 0, NULL); -} - -void -_initialize_core() -{ - struct cmd_list_element *c; - c = add_cmd ("core-file", class_files, core_file_command, - "Use FILE as core dump for examining memory and registers.\n\ -No arg means have no core file. This command has been superseded by the\n\ -`target core' and `detach' commands.", &cmdlist); - c->completer = filename_completer; - - c = add_set_cmd ("gnutarget", class_files, var_string_noescape, - (char *) &gnutarget_string, - "Set the current BFD target.\n\ -Use `set gnutarget auto' to specify automatic detection.", - &setlist); - c->function.sfunc = set_gnutarget_command; - add_show_from_set (c, &showlist); - - if (getenv ("GNUTARGET")) - set_gnutarget (getenv ("GNUTARGET")); - else - set_gnutarget ("auto"); -} diff --git a/gnu/usr.bin/gdb/gdb/coredep.c b/gnu/usr.bin/gdb/gdb/coredep.c deleted file mode 100644 index db75ff6..0000000 --- a/gnu/usr.bin/gdb/gdb/coredep.c +++ /dev/null @@ -1,124 +0,0 @@ -/* Extract registers from a "standard" core file, for GDB. - Copyright (C) 1988-1991 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. */ - -/* core.c is supposed to be the more machine-independent aspects of this; - this file is more machine-specific. */ - -#include "defs.h" -#include -#include -#include "gdbcore.h" -#include "value.h" /* For supply_register. */ -#include "inferior.h" - -/* These are needed on various systems to expand REGISTER_U_ADDR. */ -#ifndef USG -#include -#include -#include -#ifndef NO_PTRACE_H -# ifdef PTRACE_IN_WRONG_PLACE -# include -# else /* !PTRACE_IN_WRONG_PLACE */ -# include -# endif /* !PTRACE_IN_WRONG_PLACE */ -#endif /* NO_PTRACE_H */ -#endif - -#ifndef CORE_REGISTER_ADDR -#define CORE_REGISTER_ADDR(regno, regptr) register_addr(regno, regptr) -#endif /* CORE_REGISTER_ADDR */ - -#ifdef NEED_SYS_CORE_H -#include -#endif - -/* Extract the register values out of the core file and store - them where `read_register' will find them. - - CORE_REG_SECT points to the register values themselves, read into memory. - CORE_REG_SIZE is the size of that area. - WHICH says which set of registers we are handling (0 = int, 2 = float - on machines where they are discontiguous). - REG_ADDR is the offset from u.u_ar0 to the register values relative to - core_reg_sect. This is used with old-fashioned core files to - locate the registers in a large upage-plus-stack ".reg" section. - Original upage address X is at location core_reg_sect+x+reg_addr. - */ - -void -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; -{ - register int regno; - register unsigned int addr; - int bad_reg = -1; - register 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, - so we can use it as an offset into core_reg_sect. When we're done, - "register 0" will be at core_reg_sect+reg_ptr, and we can use - 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 > 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 (bad_reg >= 0) - { - error ("Register %s not found in core file.", reg_names[bad_reg]); - } -} - - -#ifdef REGISTER_U_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 -register_addr (regno, blockend) - int regno; - int blockend; -{ - int addr; - - if (regno < 0 || regno >= ARCH_NUM_REGS) - error ("Invalid register number %d.", regno); - - REGISTER_U_ADDR (addr, blockend, regno); - - return addr; -} - -#endif /* REGISTER_U_ADDR */ diff --git a/gnu/usr.bin/gdb/gdb/corelow.c b/gnu/usr.bin/gdb/gdb/corelow.c deleted file mode 100644 index 2729742..0000000 --- a/gnu/usr.bin/gdb/gdb/corelow.c +++ /dev/null @@ -1,333 +0,0 @@ -/* Core dump and executable file functions below target vector, for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include -#include -#include -#include -#include "frame.h" /* required by inferior.h */ -#include "inferior.h" -#include "symtab.h" -#include "command.h" -#include "bfd.h" -#include "target.h" -#include "gdbcore.h" -#include "thread.h" - -static void -core_files_info PARAMS ((struct target_ops *)); - -#ifdef SOLIB_ADD -static int -solib_add_stub PARAMS ((char *)); -#endif - -static void -core_close PARAMS ((int)); - -static void -get_core_registers PARAMS ((int)); - -/* Discard all vestiges of any previous core file - and mark data and stack spaces as empty. */ - -/* ARGSUSED */ -static void -core_close (quitting) - int quitting; -{ - inferior_pid = 0; /* Avoid confusion from thread stuff */ - - if (core_bfd) { - free (bfd_get_filename (core_bfd)); - bfd_close (core_bfd); - core_bfd = NULL; -#ifdef CLEAR_SOLIB - CLEAR_SOLIB (); -#endif - if (core_ops.to_sections) { - free ((PTR)core_ops.to_sections); - core_ops.to_sections = NULL; - core_ops.to_sections_end = NULL; - } - } -} - -#ifdef SOLIB_ADD -/* Stub function for catch_errors around shared library hacking. FROM_TTYP - is really an int * which points to from_tty. */ - -static int -solib_add_stub (from_ttyp) - char *from_ttyp; -{ - SOLIB_ADD (NULL, *(int *)from_ttyp, &core_ops); - return 0; -} -#endif /* SOLIB_ADD */ - -/* Look for sections whose names start with `.reg/' so that we can extract the - list of threads in a core file. */ - -static void -add_to_thread_list (abfd, asect, reg_sect_arg) - bfd *abfd; - asection *asect; - PTR reg_sect_arg; -{ - int thread_id; - asection *reg_sect = (asection *) reg_sect_arg; - - if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0) - return; - - thread_id = atoi (bfd_section_name (abfd, asect) + 5); - - add_thread (thread_id); - -/* Warning, Will Robinson, looking at BFD private data! */ - - if (asect->filepos == reg_sect->filepos) /* Did we find .reg? */ - inferior_pid = thread_id; /* Yes, make it current */ -} - -/* This routine opens and sets up the core file bfd */ - -void -core_open (filename, from_tty) - char *filename; - int from_tty; -{ - const char *p; - int siggy; - struct cleanup *old_chain; - char *temp; - bfd *temp_bfd; - int ontop; - int scratch_chan; - - target_preopen (from_tty); - if (!filename) - { - error (core_bfd? - "No core file specified. (Use `detach' to stop debugging a core file.)" - : "No core file specified."); - } - - filename = tilde_expand (filename); - if (filename[0] != '/') { - temp = concat (current_directory, "/", filename, NULL); - free (filename); - filename = temp; - } - - old_chain = make_cleanup (free, filename); - - scratch_chan = open (filename, write_files? O_RDWR: O_RDONLY, 0); - if (scratch_chan < 0) - perror_with_name (filename); - - temp_bfd = bfd_fdopenr (filename, gnutarget, scratch_chan); - if (temp_bfd == NULL) - { - perror_with_name (filename); - } - - if (!bfd_check_format (temp_bfd, bfd_core)) - { - /* Do it after the err msg */ - make_cleanup (bfd_close, temp_bfd); - error ("\"%s\" is not a core dump: %s", filename, bfd_errmsg(bfd_get_error ())); - } - - /* Looks semi-reasonable. Toss the old core file and work on the new. */ - - 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); - - validate_files (); - - /* Find the data section */ - if (build_section_table (core_bfd, &core_ops.to_sections, - &core_ops.to_sections_end)) - error ("Can't find sections in `%s': %s", bfd_get_filename(core_bfd), - bfd_errmsg (bfd_get_error ())); - - ontop = !push_target (&core_ops); - discard_cleanups (old_chain); - - p = bfd_core_file_failing_command (core_bfd); - if (p) - printf_filtered ("Core was generated by `%s'.\n", p); - - siggy = bfd_core_file_failing_signal (core_bfd); - if (siggy > 0) - printf_filtered ("Program terminated with signal %d, %s.\n", siggy, - safe_strsignal (siggy)); - - /* Build up thread list from BFD sections. */ - - init_thread_list (); - bfd_map_over_sections (core_bfd, add_to_thread_list, - bfd_get_section_by_name (core_bfd, ".reg")); - - if (ontop) { - /* Fetch all registers from core file */ - target_fetch_registers (-1); - - /* Add symbols and section mappings for any shared libraries */ -#ifdef SOLIB_ADD - catch_errors (solib_add_stub, &from_tty, (char *)0, - RETURN_MASK_ALL); -#endif - - /* Now, set up the frame cache, and print the top of stack */ - set_current_frame (create_new_frame (read_fp (), - read_pc ())); - select_frame (get_current_frame (), 0); - print_stack_frame (selected_frame, selected_frame_level, 1); - } else { - warning ( -"you won't be able to access this core file until you terminate\n\ -your %s; do ``info files''", current_target->to_longname); - } -} - -void -core_detach (args, from_tty) - char *args; - int from_tty; -{ - if (args) - error ("Too many arguments"); - unpush_target (&core_ops); - reinit_frame_cache (); - if (from_tty) - printf_filtered ("No core file now.\n"); -} - -/* Get the registers out of a core file. This is the machine- - independent part. Fetch_core_registers is the machine-dependent - part, typically implemented in the xm-file for each architecture. */ - -/* We just get all the registers, so we don't use regno. */ -/* ARGSUSED */ -static void -get_core_registers (regno) - int regno; -{ - sec_ptr reg_sec; - unsigned size; - char *the_regs; - char secname[10]; - - /* Thread support. If inferior_pid is non-zero, then we have found a core - file with threads (or multiple processes). In that case, we need to - use the appropriate register section, else we just use `.reg'. */ - - /* XXX - same thing needs to be done for floating-point (.reg2) sections. */ - - if (inferior_pid) - sprintf (secname, ".reg/%d", inferior_pid); - else - strcpy (secname, ".reg"); - - reg_sec = bfd_get_section_by_name (core_bfd, secname); - if (!reg_sec) goto cant; - size = bfd_section_size (core_bfd, reg_sec); - the_regs = alloca (size); - if (bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr)0, size)) - { - fetch_core_registers (the_regs, size, 0, - (unsigned) bfd_section_vma (abfd,reg_sec)); - } - else - { -cant: - fprintf_filtered (gdb_stderr, "Couldn't fetch registers from core file: %s\n", - bfd_errmsg (bfd_get_error ())); - } - - /* Now do it again for the float registers, if they exist. */ - reg_sec = bfd_get_section_by_name (core_bfd, ".reg2"); - if (reg_sec) { - size = bfd_section_size (core_bfd, reg_sec); - the_regs = alloca (size); - if (bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr)0, - size)) - { - fetch_core_registers (the_regs, size, 2, - (unsigned) bfd_section_vma (abfd,reg_sec)); - } - else - { - fprintf_filtered (gdb_stderr, "Couldn't fetch register set 2 from core file: %s\n", - bfd_errmsg (bfd_get_error ())); - } - } - registers_fetched(); -} - -static void -core_files_info (t) - struct target_ops *t; -{ - print_section_info (t, core_bfd); -} - -/* If mourn is being called in all the right places, this could be say - `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ - -static int -ignore (addr, contents) - CORE_ADDR addr; - char *contents; -{ - return 0; -} - -struct target_ops core_ops = { - "core", "Local core dump file", - "Use a core file as a target. Specify the filename of the core file.", - core_open, core_close, - find_default_attach, core_detach, 0, 0, /* resume, wait */ - get_core_registers, - 0, 0, /* store_regs, prepare_to_store */ - xfer_memory, core_files_info, - ignore, ignore, /* core_insert_breakpoint, core_remove_breakpoint, */ - 0, 0, 0, 0, 0, /* terminal stuff */ - 0, 0, 0, /* kill, load, lookup sym */ - find_default_create_inferior, 0, /* mourn_inferior */ - 0, /* can_run */ - 0, /* notice_signals */ - core_stratum, 0, /* next */ - 0, 1, 1, 1, 0, /* all mem, mem, stack, regs, exec */ - 0, 0, /* section pointers */ - OPS_MAGIC, /* Always the last thing */ -}; - -void -_initialize_corelow() -{ - add_target (&core_ops); -} diff --git a/gnu/usr.bin/gdb/gdb/cp-valprint.c b/gnu/usr.bin/gdb/gdb/cp-valprint.c deleted file mode 100644 index de60814..0000000 --- a/gnu/usr.bin/gdb/gdb/cp-valprint.c +++ /dev/null @@ -1,512 +0,0 @@ -/* Support for printing C++ values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991 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 "defs.h" -#include "obstack.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "value.h" -#include "command.h" -#include "gdbcmd.h" -#include "demangle.h" -#include "annotate.h" - -int vtblprint; /* Controls printing of vtbl's */ -int objectprint; /* Controls looking up an object's derived type - using what we find in its vtables. */ -struct obstack dont_print_obstack; - -static void -cplus_print_value PARAMS ((struct type *, char *, GDB_FILE *, int, int, - enum val_prettyprint, struct type **)); - -/* BEGIN-FIXME: Hooks into typeprint.c, find a better home for prototypes. */ - -extern void -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 *)); - -extern struct obstack dont_print_obstack; - -/* END-FIXME */ - -void -cp_print_class_method (valaddr, type, stream) - char *valaddr; - struct type *type; - GDB_FILE *stream; -{ - struct type *domain; - struct fn_field *f = NULL; - int j = 0; - int len2; - int offset; - char *kind = ""; - CORE_ADDR addr; - struct symbol *sym; - unsigned len; - unsigned int i; - - check_stub_type (TYPE_TARGET_TYPE (type)); - domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)); - if (domain == (struct type *)NULL) - { - fprintf_filtered (stream, ""); - return; - } - addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr); - if (METHOD_PTR_IS_VIRTUAL (addr)) - { - offset = METHOD_PTR_TO_VOFFSET (addr); - len = TYPE_NFN_FIELDS (domain); - for (i = 0; i < len; i++) - { - f = TYPE_FN_FIELDLIST1 (domain, i); - len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); - - for (j = 0; j < len2; j++) - { - QUIT; - if (TYPE_FN_FIELD_VOFFSET (f, j) == offset) - { - kind = "virtual "; - goto common; - } - } - } - } - else - { - sym = find_pc_function (addr); - if (sym == 0) - { - error ("invalid pointer to member function"); - } - len = TYPE_NFN_FIELDS (domain); - for (i = 0; i < len; i++) - { - f = TYPE_FN_FIELDLIST1 (domain, i); - len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); - - for (j = 0; j < len2; j++) - { - QUIT; - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (domain, i, j); - if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))) - { - goto common; - } - } - } - } - common: - if (i < len) - { - 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] == '_' - && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER) - { - cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1, "~", - TYPE_FN_FIELDLIST_NAME (domain, i), - 0, stream); - } - else - { - cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "", - TYPE_FN_FIELDLIST_NAME (domain, i), - 0, stream); - } - } - else - { - fprintf_filtered (stream, "("); - type_print (type, "", stream, -1); - fprintf_filtered (stream, ") %d", (int) addr >> 3); - } -} - -/* This was what it was for gcc 2.4.5 and earlier. */ -static const char vtbl_ptr_name_old[] = - { CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 }; -/* It was changed to this after 2.4.5. */ -const char vtbl_ptr_name[] = - { '_','_','v','t','b','l','_','p','t','r','_','t','y','p','e', 0 }; - -/* Return truth value for assertion that TYPE is of the type - "pointer to virtual function". */ - -int -cp_is_vtbl_ptr_type(type) - struct type *type; -{ - char *typename = type_name_no_tag (type); - - return (typename != NULL - && (STREQ (typename, vtbl_ptr_name) - || STREQ (typename, vtbl_ptr_name_old))); -} - -/* Return truth value for the assertion that TYPE is of the type - "pointer to virtual function table". */ - -int -cp_is_vtbl_member(type) - struct type *type; -{ - if (TYPE_CODE (type) == TYPE_CODE_PTR) - { - type = TYPE_TARGET_TYPE (type); - if (TYPE_CODE (type) == TYPE_CODE_ARRAY) - { - type = TYPE_TARGET_TYPE (type); - if (TYPE_CODE (type) == TYPE_CODE_STRUCT /* if not using thunks */ - || TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */ - { - /* Virtual functions tables are full of pointers - to virtual functions. */ - return cp_is_vtbl_ptr_type (type); - } - } - } - return 0; -} - -/* Mutually recursive subroutines of cplus_print_value and c_val_print to - print out a structure's fields: cp_print_value_fields and cplus_print_value. - - TYPE, VALADDR, STREAM, RECURSE, and PRETTY have the - same meanings as in cplus_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 -cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, - dont_print) - struct type *type; - char *valaddr; - GDB_FILE *stream; - int format; - int recurse; - enum val_prettyprint pretty; - struct type **dont_print; -{ - int i, len, n_baseclasses; - - check_stub_type (type); - - fprintf_filtered (stream, "{"); - len = TYPE_NFIELDS (type); - n_baseclasses = TYPE_N_BASECLASSES (type); - - /* Print out baseclasses such that we don't print - duplicates of virtual baseclasses. */ - if (n_baseclasses > 0) - cplus_print_value (type, valaddr, stream, format, recurse+1, pretty, - dont_print); - - if (!len && n_baseclasses == 1) - fprintf_filtered (stream, ""); - else - { - extern int inspect_it; - int fields_seen = 0; - - for (i = n_baseclasses; i < len; i++) - { - /* Check if static field */ - if (TYPE_FIELD_STATIC (type, i)) - 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); - 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)); - - 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_PACKED (type, i)) - { - value_ptr v; - - /* Bitfields require special handling, especially due to byte - order problems. */ - if (TYPE_FIELD_IGNORE (type, i)) - { - fputs_filtered ("", 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, - stream, format, 0, recurse + 1, pretty); - } - } - else - { - if (TYPE_FIELD_IGNORE (type, i)) - { - fputs_filtered ("", stream); - } - else - { - val_print (TYPE_FIELD_TYPE (type, i), - valaddr + TYPE_FIELD_BITPOS (type, i) / 8, - 0, stream, format, 0, recurse + 1, pretty); - } - } - annotate_field_end (); - } - - if (pretty) - { - fprintf_filtered (stream, "\n"); - print_spaces_filtered (2 * recurse, stream); - } - } - fprintf_filtered (stream, "}"); -} - -/* Special val_print routine to avoid printing multiple copies of virtual - baseclasses. */ - -static void -cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print) - struct type *type; - char *valaddr; - GDB_FILE *stream; - int format; - int recurse; - enum val_prettyprint pretty; - struct type **dont_print; -{ - struct obstack tmp_obstack; - struct type **last_dont_print - = (struct type **)obstack_next_free (&dont_print_obstack); - int i, n_baseclasses = TYPE_N_BASECLASSES (type); - - if (dont_print == 0) - { - /* If we're at top level, carve out a completely fresh - chunk of the obstack and use that until this particular - invocation returns. */ - tmp_obstack = dont_print_obstack; - /* Bump up the high-water mark. Now alpha is omega. */ - obstack_finish (&dont_print_obstack); - } - - for (i = 0; i < n_baseclasses; i++) - { - /* FIXME-32x64--assumes that a target pointer can fit in a char *. - Fix it by nuking baseclass_addr. */ - char *baddr; - int err; - char *basename; - - check_stub_type (TYPE_BASECLASS (type, i)); - basename = TYPE_NAME (TYPE_BASECLASS (type, i)); - - if (BASETYPE_VIA_VIRTUAL (type, i)) - { - struct type **first_dont_print - = (struct type **)obstack_base (&dont_print_obstack); - - int j = (struct type **)obstack_next_free (&dont_print_obstack) - - first_dont_print; - - while (--j >= 0) - if (TYPE_BASECLASS (type, i) == first_dont_print[j]) - goto flush_it; - - obstack_ptr_grow (&dont_print_obstack, TYPE_BASECLASS (type, i)); - } - - /* Fix to use baseclass_offset instead. FIXME */ - baddr = baseclass_addr (type, i, valaddr, 0, &err); - if (err == 0 && baddr == 0) - error ("could not find virtual baseclass %s\n", - basename ? basename : ""); - - if (pretty) - { - fprintf_filtered (stream, "\n"); - print_spaces_filtered (2 * recurse, 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); - if (err != 0) - { - fprintf_filtered (stream, ""); - } - else - cp_print_value_fields (TYPE_BASECLASS (type, i), baddr, stream, format, - recurse, pretty, - (struct type **) obstack_base (&dont_print_obstack)); - fputs_filtered (", ", stream); - - flush_it: - ; - } - - if (dont_print == 0) - { - /* Free the space used to deal with the printing - of this type from top level. */ - obstack_free (&dont_print_obstack, last_dont_print); - /* Reset watermark so that we can continue protecting - ourselves from whatever we were protecting ourselves. */ - dont_print_obstack = tmp_obstack; - } -} - -void -cp_print_class_member (valaddr, domain, stream, prefix) - char *valaddr; - struct type *domain; - GDB_FILE *stream; - char *prefix; -{ - - /* VAL is a byte offset into the structure type DOMAIN. - Find the name of the field for that offset and - print it. */ - int extra = 0; - int bits = 0; - register unsigned int i; - unsigned len = TYPE_NFIELDS (domain); - /* @@ Make VAL into bit offset */ - LONGEST val = unpack_long (builtin_type_int, valaddr) << 3; - for (i = TYPE_N_BASECLASSES (domain); i < len; i++) - { - int bitpos = TYPE_FIELD_BITPOS (domain, i); - QUIT; - if (val == bitpos) - break; - if (val < bitpos && i != 0) - { - /* Somehow pointing into a field. */ - i -= 1; - extra = (val - TYPE_FIELD_BITPOS (domain, i)); - if (extra & 0x7) - bits = 1; - else - extra >>= 3; - break; - } - } - if (i < len) - { - char *name; - fprintf_filtered (stream, prefix); - name = type_name_no_tag (domain); - if (name) - fputs_filtered (name, stream); - else - c_type_print_base (domain, stream, 0, 0); - fprintf_filtered (stream, "::"); - fputs_filtered (TYPE_FIELD_NAME (domain, i), stream); - if (extra) - fprintf_filtered (stream, " + %d bytes", extra); - if (bits) - fprintf_filtered (stream, " (offset in bits)"); - } - else - fprintf_filtered (stream, "%d", val >> 3); -} - -void -_initialize_cp_valprint () -{ - add_show_from_set - (add_set_cmd ("vtbl", class_support, var_boolean, (char *)&vtblprint, - "Set printing of C++ virtual function tables.", - &setprintlist), - &showprintlist); - - add_show_from_set - (add_set_cmd ("object", class_support, var_boolean, (char *)&objectprint, - "Set printing of object's derived type based on vtable info.", - &setprintlist), - &showprintlist); - - /* Give people the defaults which they are used to. */ - objectprint = 0; - vtblprint = 0; - obstack_begin (&dont_print_obstack, 32 * sizeof (struct type *)); -} diff --git a/gnu/usr.bin/gdb/gdb/dbxread.c b/gnu/usr.bin/gdb/gdb/dbxread.c deleted file mode 100644 index f6f4cc3..0000000 --- a/gnu/usr.bin/gdb/gdb/dbxread.c +++ /dev/null @@ -1,2462 +0,0 @@ -/* Read dbx symbol tables and convert to internal format, for GDB. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 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. */ - -/* This module provides three functions: dbx_symfile_init, - which initializes to read a symbol file; dbx_new_init, which - discards existing cached information when all symbols are being - discarded; and dbx_symfile_read, which reads a symbol table - from a file. - - dbx_symfile_read only does the minimum work necessary for letting the - user "name" things symbolically; it does not read the entire symtab. - Instead, it reads the external and static symbols and puts them in partial - symbol tables. When more extensive information is requested of a - file, the corresponding partial symbol table is mutated into a full - fledged symbol table by going back and reading the symbols - for real. dbx_psymtab_to_symtab() is the function that does this */ - -#include "defs.h" -#include - -#if defined(USG) || defined(__CYGNUSCLIB__) -#include -#include -#endif - -#include -#include -#ifndef NO_SYS_FILE -#include -#endif -#include -#include -#include "symtab.h" -#include "breakpoint.h" -#include "command.h" -#include "target.h" -#include "gdbcore.h" /* for bfd stuff */ -#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */ -#include "symfile.h" -#include "objfiles.h" -#include "buildsym.h" -#include "stabsread.h" -#include "gdb-stabs.h" -#include "demangle.h" -#include "language.h" /* Needed inside partial-stab.h */ -#include "complaints.h" - -#include "aout/aout64.h" -#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */ - -#if !defined (SEEK_SET) -#define SEEK_SET 0 -#define SEEK_CUR 1 -#endif - -/* Each partial symbol table entry contains a pointer to private data for the - read_symtab() function to use when expanding a partial symbol table entry - to a full symbol table entry. - - For dbxread this structure contains the offset within the file symbol table - of first local symbol for this file, and 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). It also contains - further information needed to locate the symbols if they are in an ELF file. - - 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. */ - -#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)) -#define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size) -#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset) -#define STRING_OFFSET(p) (SYMLOC(p)->string_offset) -#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset) - -struct symloc { - int ldsymoff; - int ldsymlen; - int symbol_size; - int symbol_offset; - int string_offset; - int 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. */ - -static bfd *symfile_bfd; - -/* The size of each symbol in the symbol file (in external form). - This is set by dbx_symfile_read when building psymtabs, and by - dbx_psymtab_to_symtab when building symtabs. */ - -static unsigned symbol_size; - -/* 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 */ -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. */ -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. */ - -static int symfile_relocatable = 0; - - /* 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; - -/* This is the lowest text address we have yet encountered. */ -static CORE_ADDR lowest_text_address; - -/* Complaints about the symbols we have encountered. */ - -struct complaint lbrac_complaint = - {"bad block start address patched", 0, 0}; - -struct complaint string_table_offset_complaint = - {"bad string table offset in symbol %d", 0, 0}; - -struct complaint unknown_symtype_complaint = - {"unknown symbol type %s", 0, 0}; - -struct complaint unknown_symchar_complaint = - {"unknown symbol descriptor `%c'", 0, 0}; - -struct complaint lbrac_rbrac_complaint = - {"block start larger than block end", 0, 0}; - -struct complaint lbrac_unmatched_complaint = - {"unmatched N_LBRAC before symtab pos %d", 0, 0}; - -struct complaint lbrac_mismatch_complaint = - {"N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", 0, 0}; - -struct complaint repeated_header_complaint = - {"\"repeated\" header file not previously seen, at symtab pos %d", 0, 0}; - -struct complaint repeated_header_name_complaint = - {"\"repeated\" header file not previously seen, named %s", 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 - is used during readin to setup the list of dependencies within each - partial symbol table. */ - -struct header_file_location -{ - char *name; /* Name of header file */ - int instance; /* See above */ - struct partial_symtab *pst; /* Partial symtab that has the - BINCL/EINCL defs for this file */ -}; - -/* The actual list and controling variables */ -static struct header_file_location *bincl_list, *next_bincl; -static int bincls_allocated; - -/* Local function prototypes */ - -static void -free_header_files PARAMS ((void)); - -static void -init_header_files PARAMS ((void)); - -static void -read_ofile_symtab PARAMS ((struct partial_symtab *)); - -static void -dbx_psymtab_to_symtab PARAMS ((struct partial_symtab *)); - -static void -dbx_psymtab_to_symtab_1 PARAMS ((struct partial_symtab *)); - -static void -read_dbx_dynamic_symtab PARAMS ((struct section_offsets *, - struct objfile *objfile)); - -static void -read_dbx_symtab PARAMS ((struct section_offsets *, struct objfile *, - CORE_ADDR, int)); - -static void -free_bincl_list PARAMS ((struct objfile *)); - -static struct partial_symtab * -find_corresponding_bincl_psymtab PARAMS ((char *, int)); - -static void -add_bincl_to_list PARAMS ((struct partial_symtab *, char *, int)); - -static void -init_bincl_list PARAMS ((int, struct objfile *)); - -static void -init_psymbol_list PARAMS ((struct objfile *)); - -static char * -dbx_next_symbol_text PARAMS ((void)); - -static void -fill_symbuf PARAMS ((bfd *)); - -static void -dbx_symfile_init PARAMS ((struct objfile *)); - -static void -dbx_new_init PARAMS ((struct objfile *)); - -static void -dbx_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int)); - -static void -dbx_symfile_finish PARAMS ((struct objfile *)); - -static void -record_minimal_symbol PARAMS ((char *, CORE_ADDR, int, struct objfile *)); - -static void -add_new_header_file PARAMS ((char *, int)); - -static void -add_old_header_file PARAMS ((char *, int)); - -static void -add_this_object_header_file PARAMS ((int)); - -/* Free up old header file tables */ - -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; -} - -/* Allocate new header file tables */ - -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)); -} - -/* Add header file number I for this object file - at the next successive FILENUM. */ - -static void -add_this_object_header_file (i) - int i; -{ - if (n_this_object_header_files == n_allocated_this_object_header_files) - { - n_allocated_this_object_header_files *= 2; - this_object_header_files - = (int *) xrealloc ((char *) this_object_header_files, - n_allocated_this_object_header_files * sizeof (int)); - } - - this_object_header_files[n_this_object_header_files++] = i; -} - -/* Add to this file an "old" header file, one already seen in - a previous object file. NAME is the header file's name. - INSTANCE is its instance code, to select among multiple - symbol tables for the same header file. */ - -static void -add_old_header_file (name, instance) - char *name; - int instance; -{ - register struct header_file *p = header_files; - register int i; - - for (i = 0; i < n_header_files; i++) - if (STREQ (p[i].name, name) && instance == p[i].instance) - { - add_this_object_header_file (i); - return; - } - complain (&repeated_header_complaint, symnum); - complain (&repeated_header_name_complaint, name); -} - -/* Add to this file a "new" header file: definitions for its types follow. - NAME is the header file's name. - Most often this happens only once for each distinct header file, - but not necessarily. If it happens more than once, INSTANCE has - a different value each time, and references to the header file - use INSTANCE values to select among them. - - dbx output contains "begin" and "end" markers for each new header file, - but at this level we just need to know which files there have been; - so we record the file when its "begin" is seen and ignore the "end". */ - -static void -add_new_header_file (name, instance) - char *name; - int instance; -{ - register int i; - - /* Make sure there is room for one more header file. */ - - if (n_header_files == n_allocated_header_files) - { - n_allocated_header_files *= 2; - header_files = (struct header_file *) - xrealloc ((char *) header_files, - (n_allocated_header_files * 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 - = (struct type **) xmalloc (10 * sizeof (struct type *)); - memset (header_files[i].vector, 0, 10 * sizeof (struct type *)); - - add_this_object_header_file (i); -} - -#if 0 -static struct type ** -explicit_lookup_type (real_filenum, index) - int real_filenum, index; -{ - register struct header_file *f = &header_files[real_filenum]; - - if (index >= f->length) - { - f->length *= 2; - f->vector = (struct type **) - xrealloc (f->vector, f->length * sizeof (struct type *)); - memset (&f->vector[f->length / 2], - '\0', f->length * sizeof (struct type *) / 2); - } - return &f->vector[index]; -} -#endif - -static void -record_minimal_symbol (name, address, type, objfile) - char *name; - CORE_ADDR address; - int type; - struct objfile *objfile; -{ - enum minimal_symbol_type ms_type; - int section; - - switch (type) - { - case N_TEXT | N_EXT: - ms_type = mst_text; - section = SECT_OFF_TEXT; - break; - case N_DATA | N_EXT: - ms_type = mst_data; - section = SECT_OFF_DATA; - break; - case N_BSS | N_EXT: - ms_type = mst_bss; - section = SECT_OFF_BSS; - break; - case N_ABS | N_EXT: - ms_type = mst_abs; - section = -1; - break; -#ifdef N_SETV - case N_SETV | N_EXT: - ms_type = mst_data; - section = SECT_OFF_DATA; - break; - case N_SETV: - /* I don't think this type actually exists; since a N_SETV is the result - of going over many .o files, it doesn't make sense to have one - file local. */ - ms_type = mst_file_data; - section = SECT_OFF_DATA; - break; -#endif - case N_TEXT: - case N_NBTEXT: - case N_FN: - case N_FN_SEQ: - ms_type = mst_file_text; - section = SECT_OFF_TEXT; - break; - case N_DATA: - ms_type = mst_file_data; - - /* Check for __DYNAMIC, which is used by Sun shared libraries. - Record it as global even if it's local, not global, so - lookup_minimal_symbol can find it. We don't check symbol_leading_char - because for SunOS4 it always is '_'. */ - if (name[8] == 'C' && STREQ ("__DYNAMIC", name)) - ms_type = mst_data; - - /* Same with virtual function tables, both global and static. */ - { - char *tempstring = name; - if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd)) - ++tempstring; - if (VTBL_PREFIX_P ((tempstring))) - ms_type = mst_data; - } - section = SECT_OFF_DATA; - break; - case N_BSS: - ms_type = mst_file_bss; - section = SECT_OFF_BSS; - break; - default: - ms_type = mst_unknown; - section = -1; - break; - } - - if ((ms_type == mst_file_text || ms_type == mst_text) - && address < lowest_text_address) - lowest_text_address = address; - - prim_record_minimal_symbol_and_info - (obsavestring (name, strlen (name), &objfile -> symbol_obstack), - address, - ms_type, - NULL, - section, - objfile); -} - -/* Scan and build partial symbols for a symbol file. - We have been initialized by a call to dbx_symfile_init, which - put all the relevant info into a "struct dbx_symfile_info", - hung off the objfile structure. - - 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). */ - -static void -dbx_symfile_read (objfile, section_offsets, mainline) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; /* FIXME comments above */ -{ - bfd *sym_bfd; - int val; - struct cleanup *back_to; - - val = strlen (objfile->name); - - /* .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. */ - - if (strcmp (&objfile->name[val-2], ".o") == 0 - || strcmp (&objfile->name[val-4], ".nlm") == 0) - symfile_relocatable = 1; - - /* 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), "nlm", 3))); - - sym_bfd = objfile->obfd; - val = bfd_seek (objfile->obfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET); - if (val < 0) - perror_with_name (objfile->name); - - /* If we are reinitializing, or if we have never loaded syms yet, init */ - if (mainline || objfile->global_psymbols.size == 0 || objfile->static_psymbols.size == 0) - init_psymbol_list (objfile); - - symbol_size = DBX_SYMBOL_SIZE (objfile); - symbol_table_offset = DBX_SYMTAB_OFFSET (objfile); - - pending_blocks = 0; - back_to = make_cleanup (really_free_pendings, 0); - - init_minimal_symbol_collection (); - make_cleanup (discard_minimal_symbols, 0); - - /* Now that the symbol table data of the executable file are all in core, - process them and define symbols accordingly. */ - - read_dbx_symtab (section_offsets, objfile, - bfd_section_vma (sym_bfd, DBX_TEXT_SECT (objfile)), - bfd_section_size (sym_bfd, DBX_TEXT_SECT (objfile))); - - /* Add the dynamic symbols. */ - - read_dbx_dynamic_symtab (section_offsets, objfile); - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); - - do_cleanups (back_to); -} - -/* 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). */ - -static void -dbx_new_init (ignore) - struct objfile *ignore; -{ - stabsread_new_init (); - buildsym_new_init (); - init_header_files (); -} - - -/* dbx_symfile_init () - is the dbx-specific initialization routine for reading symbols. - It is passed a struct objfile which contains, among other things, - the BFD for the file whose symbols are being read, and a slot for a pointer - to "private data" which we fill with goodies. - - We read the string table into malloc'd space and stash a pointer to it. - - 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. We will never - be called unless this is an a.out (or very similar) file. - FIXME, there should be a cleaner peephole into the BFD environment here. */ - -#define DBX_STRINGTAB_SIZE_SIZE sizeof(long) /* FIXME */ - -static void -dbx_symfile_init (objfile) - struct objfile *objfile; -{ - int val; - bfd *sym_bfd = objfile->obfd; - char *name = bfd_get_filename (sym_bfd); - unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE]; - - /* Allocate struct to keep track of the symfile */ - objfile->sym_stab_info = (PTR) - xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info)); - - /* FIXME POKING INSIDE BFD DATA STRUCTURES */ -#define STRING_TABLE_OFFSET (sym_bfd->origin + obj_str_filepos (sym_bfd)) -#define SYMBOL_TABLE_OFFSET (sym_bfd->origin + obj_sym_filepos (sym_bfd)) - - /* FIXME POKING INSIDE BFD DATA STRUCTURES */ - - DBX_SYMFILE_INFO (objfile)->stab_section_info = NULL; - DBX_TEXT_SECT (objfile) = bfd_get_section_by_name (sym_bfd, ".text"); - if (!DBX_TEXT_SECT (objfile)) - error ("Can't find .text section in symbol file"); - - DBX_SYMBOL_SIZE (objfile) = obj_symbol_entry_size (sym_bfd); - DBX_SYMCOUNT (objfile) = bfd_get_symcount (sym_bfd); - DBX_SYMTAB_OFFSET (objfile) = SYMBOL_TABLE_OFFSET; - - /* Read the string table and stash it away in the psymbol_obstack. It is - only needed as long as we need to expand psymbols into full symbols, - so when we blow away the psymbol the string table goes away as well. - Note that gdb used to use the results of attempting to malloc the - string table, based on the size it read, as a form of sanity check - for botched byte swapping, on the theory that a byte swapped string - table size would be so totally bogus that the malloc would fail. Now - that we put in on the psymbol_obstack, we can't do this since gdb gets - a fatal error (out of virtual memory) if the size is bogus. We can - however at least check to see if the size is less than the size of - the size field itself, or larger than the size of the entire file. - Note that all valid string tables have a size greater than zero, since - the bytes used to hold the size are included in the count. */ - - if (STRING_TABLE_OFFSET == 0) - { - /* It appears that with the existing bfd code, STRING_TABLE_OFFSET - will never be zero, even when there is no string table. This - would appear to be a bug in bfd. */ - DBX_STRINGTAB_SIZE (objfile) = 0; - DBX_STRINGTAB (objfile) = NULL; - } - else - { - val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET); - if (val < 0) - perror_with_name (name); - - memset ((PTR) size_temp, 0, sizeof (size_temp)); - val = bfd_read ((PTR) size_temp, sizeof (size_temp), 1, sym_bfd); - if (val < 0) - { - perror_with_name (name); - } - else if (val == 0) - { - /* With the existing bfd code, STRING_TABLE_OFFSET will be set to - EOF if there is no string table, and attempting to read the size - from EOF will read zero bytes. */ - DBX_STRINGTAB_SIZE (objfile) = 0; - DBX_STRINGTAB (objfile) = NULL; - } - else - { - /* Read some data that would appear to be the string table size. - If there really is a string table, then it is probably the right - size. Byteswap if necessary and validate the size. Note that - the minimum is DBX_STRINGTAB_SIZE_SIZE. If we just read some - random data that happened to be at STRING_TABLE_OFFSET, because - bfd can't tell us there is no string table, the sanity checks may - or may not catch this. */ - DBX_STRINGTAB_SIZE (objfile) = bfd_h_get_32 (sym_bfd, size_temp); - - if (DBX_STRINGTAB_SIZE (objfile) < sizeof (size_temp) - || DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd)) - error ("ridiculous string table size (%d bytes).", - DBX_STRINGTAB_SIZE (objfile)); - - DBX_STRINGTAB (objfile) = - (char *) obstack_alloc (&objfile -> psymbol_obstack, - DBX_STRINGTAB_SIZE (objfile)); - - /* Now read in the string table in one big gulp. */ - - val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET); - if (val < 0) - perror_with_name (name); - val = bfd_read (DBX_STRINGTAB (objfile), DBX_STRINGTAB_SIZE (objfile), 1, - sym_bfd); - if (val != DBX_STRINGTAB_SIZE (objfile)) - perror_with_name (name); - } - } -} - -/* 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. */ - -static void -dbx_symfile_finish (objfile) - struct objfile *objfile; -{ - if (objfile->sym_stab_info != NULL) - { - mfree (objfile -> md, objfile->sym_stab_info); - } - free_header_files (); -} - - -/* Buffer for reading the symbol table entries. */ -static struct internal_nlist symbuf[4096]; -static int symbuf_idx; -static int symbuf_end; - -/* Name of last function encountered. Used in Solaris to approximate - object file boundaries. */ -static char *last_function_name; - -/* The address in memory of the string table of the object file we are - reading (which might not be the "main" object file, but might be a - shared library or some other dynamically loaded thing). This is set - by read_dbx_symtab when building psymtabs, and by read_ofile_symtab - when building symtabs, and is used only by next_symbol_text. */ -static char *stringtab_global; - -/* Refill the symbol table input buffer - and set the variables that control fetching entries from it. - Reports an error if no data available. - This function can read past the end of the symbol table - (into the string table) but this does no harm. */ - -static void -fill_symbuf (sym_bfd) - bfd *sym_bfd; -{ - int nbytes = bfd_read ((PTR)symbuf, sizeof (symbuf), 1, sym_bfd); - if (nbytes < 0) - perror_with_name (bfd_get_filename (sym_bfd)); - else if (nbytes == 0) - error ("Premature end of file reading symbol table"); - symbuf_end = nbytes / symbol_size; - symbuf_idx = 0; -} - -#define SWAP_SYMBOL(symp, abfd) \ - { \ - (symp)->n_strx = bfd_h_get_32(abfd, \ - (unsigned char *)&(symp)->n_strx); \ - (symp)->n_desc = bfd_h_get_16 (abfd, \ - (unsigned char *)&(symp)->n_desc); \ - (symp)->n_value = bfd_h_get_32 (abfd, \ - (unsigned char *)&(symp)->n_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. */ - -/* dbx allows the text of a symbol name to be continued into the - next symbol name! When such a continuation is encountered - (a \ at the end of the text of a name) - call this function to get the continuation. */ - -static char * -dbx_next_symbol_text () -{ - if (symbuf_idx == symbuf_end) - fill_symbuf (symfile_bfd); - symnum++; - SWAP_SYMBOL(&symbuf[symbuf_idx], symfile_bfd); - return symbuf[symbuf_idx++].n_strx + stringtab_global - + file_string_table_offset; -} - -/* Initializes storage for all of the partial symbols that will be - created by read_dbx_symtab and subsidiaries. */ - -static void -init_psymbol_list (objfile) - struct objfile *objfile; -{ - /* Free any previously allocated psymbol lists. */ - if (objfile -> global_psymbols.list) - mfree (objfile -> md, (PTR)objfile -> global_psymbols.list); - if (objfile -> static_psymbols.list) - mfree (objfile -> md, (PTR)objfile -> static_psymbols.list); - - /* Current best guess is that there are approximately a twentieth - of the total symbols (in a debugging file) are global or static - oriented symbols */ - objfile -> global_psymbols.size = DBX_SYMCOUNT (objfile) / 10; - objfile -> static_psymbols.size = DBX_SYMCOUNT (objfile) / 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)); -} - -/* Initialize the list of bincls to contain none and have some - allocated. */ - -static void -init_bincl_list (number, objfile) - int number; - struct objfile *objfile; -{ - bincls_allocated = number; - next_bincl = bincl_list = (struct header_file_location *) - xmmalloc (objfile -> md, bincls_allocated * sizeof(struct header_file_location)); -} - -/* Add a bincl to the list. */ - -static void -add_bincl_to_list (pst, name, instance) - struct partial_symtab *pst; - char *name; - int instance; -{ - if (next_bincl >= bincl_list + bincls_allocated) - { - int offset = next_bincl - bincl_list; - bincls_allocated *= 2; - bincl_list = (struct header_file_location *) - xmrealloc (pst->objfile->md, (char *)bincl_list, - bincls_allocated * sizeof (struct header_file_location)); - next_bincl = bincl_list + offset; - } - next_bincl->pst = pst; - next_bincl->instance = instance; - next_bincl++->name = name; -} - -/* Given a name, value pair, find the corresponding - bincl in the list. Return the partial symtab associated - with that header_file_location. */ - -static struct partial_symtab * -find_corresponding_bincl_psymtab (name, instance) - char *name; - int instance; -{ - struct header_file_location *bincl; - - for (bincl = bincl_list; bincl < next_bincl; bincl++) - if (bincl->instance == instance - && STREQ (name, bincl->name)) - return bincl->pst; - - return (struct partial_symtab *) 0; -} - -/* Free the storage allocated for the bincl list. */ - -static void -free_bincl_list (objfile) - struct objfile *objfile; -{ - mfree (objfile -> md, (PTR)bincl_list); - bincls_allocated = 0; -} - -/* Scan a SunOs dynamic symbol table for symbols of interest and - add them to the minimal symbol table. */ - -static void -read_dbx_dynamic_symtab (section_offsets, objfile) - struct section_offsets *section_offsets; - struct objfile *objfile; -{ - bfd *abfd = objfile->obfd; - struct cleanup *back_to; - int counter; - long dynsym_size; - long dynsym_count; - asymbol **dynsyms; - asymbol **symptr; - arelent **relptr; - long dynrel_size; - long dynrel_count; - arelent **dynrels; - CORE_ADDR sym_value; - - /* Check that the symbol file has dynamic symbols that we know about. - bfd_arch_unknown can happen if we are reading a sun3 symbol file - on a sun4 host (and vice versa) and bfd is not configured - --with-target=all. This would trigger an assertion in bfd/sunos.c, - so we ignore the dynamic symbols in this case. */ - if (bfd_get_flavour (abfd) != bfd_target_aout_flavour - || (bfd_get_file_flags (abfd) & DYNAMIC) == 0 - || bfd_get_arch (abfd) == bfd_arch_unknown) - return; - - dynsym_size = bfd_get_dynamic_symtab_upper_bound (abfd); - if (dynsym_size < 0) - return; - - dynsyms = (asymbol **) xmalloc (dynsym_size); - back_to = make_cleanup (free, dynsyms); - - dynsym_count = bfd_canonicalize_dynamic_symtab (abfd, dynsyms); - if (dynsym_count < 0) - { - do_cleanups (back_to); - return; - } - - /* Enter dynamic symbols into the minimal symbol table - if this is a stripped executable. */ - if (bfd_get_symcount (abfd) <= 0) - { - symptr = dynsyms; - for (counter = 0; counter < dynsym_count; counter++, symptr++) - { - asymbol *sym = *symptr; - asection *sec; - int type; - - sec = bfd_get_section (sym); - - /* BFD symbols are section relative. */ - sym_value = sym->value + sec->vma; - - if (bfd_get_section_flags (abfd, sec) & SEC_CODE) - { - sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT); - type = N_TEXT; - } - else if (bfd_get_section_flags (abfd, sec) & SEC_DATA) - { - sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA); - type = N_DATA; - } - else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC) - { - sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS); - type = N_BSS; - } - else - continue; - - if (sym->flags & BSF_GLOBAL) - type |= N_EXT; - - record_minimal_symbol ((char *) bfd_asymbol_name (sym), sym_value, - type, objfile); - } - } - - /* Symbols from shared libraries have a dynamic relocation entry - that points to the associated slot in the procedure linkage table. - We make a mininal symbol table entry with type mst_solib_trampoline - at the address in the procedure linkage table. */ - dynrel_size = bfd_get_dynamic_reloc_upper_bound (abfd); - if (dynrel_size < 0) - { - do_cleanups (back_to); - return; - } - - dynrels = (arelent **) xmalloc (dynrel_size); - make_cleanup (free, dynrels); - - dynrel_count = bfd_canonicalize_dynamic_reloc (abfd, dynrels, dynsyms); - if (dynrel_count < 0) - { - do_cleanups (back_to); - return; - } - - for (counter = 0, relptr = dynrels; - counter < dynrel_count; - counter++, relptr++) - { - arelent *rel = *relptr; - CORE_ADDR address = - rel->address + ANOFFSET (section_offsets, SECT_OFF_DATA); - - switch (bfd_get_arch (abfd)) - { - case bfd_arch_sparc: - if (rel->howto->type != RELOC_JMP_SLOT) - continue; - break; - case bfd_arch_m68k: - /* `16' is the type BFD produces for a jump table relocation. */ - if (rel->howto->type != 16) - continue; - - /* Adjust address in the jump table to point to - the start of the bsr instruction. */ - address -= 2; - break; - default: - continue; - } - - prim_record_minimal_symbol (bfd_asymbol_name (*rel->sym_ptr_ptr), - address, - mst_solib_trampoline, - objfile); - } - - do_cleanups (back_to); -} - -/* Given pointers to an a.out symbol table in core containing dbx - style data, setup partial_symtab's describing each source file for - which debugging information is available. - SYMFILE_NAME is the name of the file we are reading from - and SECTION_OFFSETS is the set of offsets for the various sections - of the file (a set of zeros if the mainline program). */ - -static void -read_dbx_symtab (section_offsets, objfile, text_addr, text_size) - struct section_offsets *section_offsets; - struct objfile *objfile; - CORE_ADDR text_addr; - int text_size; -{ - register struct internal_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */ - register char *namestring; - int nsl; - int past_first_source_file = 0; - CORE_ADDR last_o_file_start = 0; - struct cleanup *back_to; - bfd *abfd; - - /* 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; - - /* FIXME. We probably want to change stringtab_global rather than add this - while processing every symbol entry. FIXME. */ - file_string_table_offset = 0; - next_file_string_table_offset = 0; - - stringtab_global = DBX_STRINGTAB (objfile); - - pst = (struct partial_symtab *) 0; - - 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 *)); - - /* Init bincl list */ - init_bincl_list (20, objfile); - back_to = make_cleanup (free_bincl_list, objfile); - - last_source_file = NULL; - - lowest_text_address = (CORE_ADDR)-1; - - symfile_bfd = objfile->obfd; /* For next_text_symbol */ - abfd = objfile->obfd; - symbuf_end = symbuf_idx = 0; - next_symbol_text_func = dbx_next_symbol_text; - - for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++) - { - /* Get the symbol for this run and pull out some info */ - QUIT; /* allow this to be interruptable */ - if (symbuf_idx == symbuf_end) - fill_symbuf (abfd); - bufp = &symbuf[symbuf_idx++]; - - /* - * Special case to speed up readin. - */ - if (bufp->n_type == (unsigned char)N_SLINE) continue; - - SWAP_SYMBOL (bufp, abfd); - - /* Ok. There is a lot of code duplicated in the rest of this - switch statement (for efficiency reasons). Since I don't - like duplicating code, I will do my penance here, and - describe the code which is duplicated: - - *) The assignment to namestring. - *) The call to strchr. - *) The addition of a partial symbol the the two partial - symbol lists. This last is a large section of code, so - I've imbedded it in the following macro. - */ - -/* Set namestring based on bufp. 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) >= \ - DBX_STRINGTAB_SIZE (objfile)) { \ - complain (&string_table_offset_complaint, symnum); \ - namestring = ""; \ - } else \ - namestring = bufp->n_strx + file_string_table_offset + \ - DBX_STRINGTAB (objfile) - -#define CUR_SYMBOL_TYPE bufp->n_type -#define CUR_SYMBOL_VALUE bufp->n_value -#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) - -#include "partial-stab.h" - } - - /* If there's stuff to be cleaned up, clean it up. */ - 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 >= last_o_file_start) - { - objfile -> ei.entry_file_lowpc = last_o_file_start; - objfile -> ei.entry_file_highpc = bufp->n_value; - } - - if (pst) - { - 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); - } - - do_cleanups (back_to); -} - -/* 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). */ - - -struct partial_symtab * -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; -{ - struct partial_symtab *result = - start_psymtab_common(objfile, section_offsets, - filename, textlow, global_syms, static_syms); - - result->read_symtab_private = (char *) - obstack_alloc (&objfile -> psymbol_obstack, sizeof (struct symloc)); - LDSYMOFF(result) = ldsymoff; - result->read_symtab = dbx_psymtab_to_symtab; - SYMBOL_SIZE(result) = symbol_size; - SYMBOL_OFFSET(result) = symbol_table_offset; - STRING_OFFSET(result) = string_table_offset; - FILE_STRING_OFFSET(result) = file_string_table_offset; - - /* If we're handling an ELF file, drag some section-relocation info - for this source file out of the ELF symbol table, to compensate for - Sun brain death. This replaces the section_offsets in this psymtab, - if successful. */ - elfstab_offset_sections (objfile, result); - - /* Deduce the source language from the filename for this psymtab. */ - psymtab_language = deduce_language_from_filename (filename); - - return result; -} - -/* Close off the current usage of PST. - Returns PST or NULL if the partial symtab was empty and thrown away. - - FIXME: List variables and peculiarities of same. */ - -struct partial_symtab * -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; - - if (capping_symbol_offset != -1) - LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst); - pst->texthigh = capping_text; - -#ifdef N_SO_ADDRESS_MAYBE_MISSING - /* Under Solaris, the N_SO symbols always have a value of 0, - instead of the usual address of the .o file. Therefore, - 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. - - 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 - bfd/elf.c and gdb/elfread.c to pass the ELF st_size field - to here via the misc_info field. Therefore, we can fill in - a reliable texthigh by taking the address plus size of the - last function in the file. - - Unfortunately, that does not cover the case where the last function - in the file is static. See the paragraph below for more comments - on this situation. - - Finally, if we have a valid textlow for the current file, we run - down the partial_symtab_list filling in previous texthighs that - are still unknown. */ - - 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; - - minsym = lookup_minimal_symbol (p, objfile); - - if (minsym) { - pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + - (long) MSYMBOL_INFO (minsym); - } else { - /* This file ends with a static function, and it's - difficult to imagine how hard it would be to track down - the elf symbol. Luckily, most of the time no one will notice, - since the next file will likely be compiled with -g, so - the code below will copy the first fuction's start address - back to our texthigh variable. (Also, if this file is the - last one in a dynamically linked program, texthigh already - has the right value.) If the next file isn't compiled - with -g, then the last function in this file winds up owning - all of the text space up to the next -g file, or the end (minus - shared libraries). This only matters for single stepping, - and even then it will still work, except that it will single - step through all of the covered functions, instead of setting - breakpoints around them as it usualy does. This makes it - pretty slow, but at least it doesn't fail. - - We can fix this with a fairly big change to bfd, but we need - to coordinate better with Cygnus if we want to do that. FIXME. */ - } - 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 N_SO_ADDRESS_MAYBE_MISSING. */ - pst->textlow = pst->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. */ - 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; - } - } - } - - /* End of kludge for patching Solaris textlow and texthigh. */ -#endif /* N_SO_ADDRESS_MAYBE_MISSING. */ - - 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); - - 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. */ - 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; - - /* Indicate that psymtab was thrown away. */ - pst = (struct partial_symtab *)NULL; - } - return pst; -} - -static void -dbx_psymtab_to_symtab_1 (pst) - struct partial_symtab *pst; -{ - struct cleanup *old_chain; - int i; - - if (!pst) - return; - - if (pst->readin) - { - fprintf_unfiltered (gdb_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); - } - dbx_psymtab_to_symtab_1 (pst->dependencies[i]); - } - - if (LDSYMLEN(pst)) /* Otherwise it's a dummy */ - { - /* Init stuff necessary for reading in symbols */ - stabsread_init (); - buildsym_init (); - old_chain = make_cleanup (really_free_pendings, 0); - file_string_table_offset = FILE_STRING_OFFSET (pst); - symbol_size = SYMBOL_SIZE (pst); - - /* Read in this file's symbols */ - bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET); - read_ofile_symtab (pst); - 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. */ - -static void -dbx_psymtab_to_symtab (pst) - struct partial_symtab *pst; -{ - bfd *sym_bfd; - - if (!pst) - return; - - if (pst->readin) - { - fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n", - pst->filename); - return; - } - - 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); - } - - sym_bfd = pst->objfile->obfd; - - next_symbol_text_func = dbx_next_symbol_text; - - dbx_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. */ - -static void -read_ofile_symtab (pst) - struct partial_symtab *pst; -{ - register char *namestring; - register struct internal_nlist *bufp; - unsigned char type; - unsigned max_symnum; - register bfd *abfd; - struct objfile *objfile; - int sym_offset; /* Offset to start of symbols to read */ - int sym_size; /* Size of symbols to read */ - CORE_ADDR text_offset; /* Start of text segment for symbols */ - int text_size; /* Size of text segment for symbols */ - struct section_offsets *section_offsets; - - objfile = pst->objfile; - sym_offset = LDSYMOFF(pst); - sym_size = LDSYMLEN(pst); - text_offset = pst->textlow; - text_size = pst->texthigh - pst->textlow; - section_offsets = pst->section_offsets; - - current_objfile = objfile; - subfile_stack = NULL; - - stringtab_global = DBX_STRINGTAB (objfile); - last_source_file = NULL; - - abfd = objfile->obfd; - symfile_bfd = objfile->obfd; /* Implicit param to next_text_symbol */ - symbuf_end = symbuf_idx = 0; - - /* It is necessary to actually read one symbol *before* the start - of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL - occurs before the N_SO symbol. - - Detecting this in read_dbx_symtab - would slow down initial readin, so we look for it here instead. */ - if (!processing_acc_compilation && sym_offset >= (int)symbol_size) - { - bfd_seek (symfile_bfd, sym_offset - symbol_size, SEEK_CUR); - fill_symbuf (abfd); - bufp = &symbuf[symbuf_idx++]; - SWAP_SYMBOL (bufp, abfd); - - SET_NAMESTRING (); - - processing_gcc_compilation = 0; - if (bufp->n_type == N_TEXT) - { - const char *tempstring = namestring; - - if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL)) - processing_gcc_compilation = 1; - else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL)) - processing_gcc_compilation = 2; - if (tempstring[0] == bfd_get_symbol_leading_char (symfile_bfd)) - ++tempstring; - if (STREQN (tempstring, "__gnu_compiled", 14)) - processing_gcc_compilation = 2; - } - - /* Try to select a C++ demangling based on the compilation unit - producer. */ - - if (processing_gcc_compilation) - { - if (AUTO_DEMANGLING) - { - set_demangling_style (GNU_DEMANGLING_STYLE_STRING); - } - } - } - else - { - /* The N_SO starting this symtab is the first symbol, so we - better not check the symbol before it. I'm not this can - happen, but it doesn't hurt to check for it. */ - bfd_seek (symfile_bfd, sym_offset, SEEK_CUR); - processing_gcc_compilation = 0; - } - - if (symbuf_idx == symbuf_end) - fill_symbuf (abfd); - bufp = &symbuf[symbuf_idx]; - if (bufp->n_type != (unsigned char)N_SO) - error("First symbol in segment of executable not a source symbol"); - - max_symnum = sym_size / symbol_size; - - for (symnum = 0; - symnum < max_symnum; - symnum++) - { - QUIT; /* Allow this to be interruptable */ - if (symbuf_idx == symbuf_end) - fill_symbuf(abfd); - bufp = &symbuf[symbuf_idx++]; - SWAP_SYMBOL (bufp, abfd); - - type = bufp->n_type; - - SET_NAMESTRING (); - - if (type & N_STAB) { - process_one_symbol (type, bufp->n_desc, bufp->n_value, - namestring, section_offsets, objfile); - } - /* We skip checking for a new .o or -l file; that should never - happen in this routine. */ - else if (type == N_TEXT) - { - /* I don't think this code will ever be executed, because - the GCC_COMPILED_FLAG_SYMBOL usually is right before - the N_SO symbol which starts this source file. - However, there is no reason not to accept - the GCC_COMPILED_FLAG_SYMBOL anywhere. */ - - if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL)) - processing_gcc_compilation = 1; - else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL)) - processing_gcc_compilation = 2; - - if (AUTO_DEMANGLING) - { - set_demangling_style (GNU_DEMANGLING_STYLE_STRING); - } - } - else if (type & N_EXT || type == (unsigned char)N_TEXT - || type == (unsigned char)N_NBTEXT - ) { - /* Global symbol: see if we came across a dbx defintion for - a corresponding symbol. If so, store the value. Remove - syms from the chain when their values are stored, but - search the whole chain, as there may be several syms from - different files with the same name. */ - /* This is probably not true. Since the files will be read - in one at a time, each reference to a global symbol will - be satisfied in each file as it appears. So we skip this - section. */ - ; - } - } - - current_objfile = NULL; - - /* In a Solaris elf file, this variable, which comes from the - value of the N_SO symbol, will still be 0. Luckily, text_offset, - which comes from pst->textlow is correct. */ - if (last_source_start_addr == 0) - last_source_start_addr = text_offset; - - pst->symtab = end_symtab (text_offset + text_size, 0, 0, objfile, - SECT_OFF_TEXT); - end_stabs (); -} - - -/* This handles a single symbol from the symbol-file, building symbols - into a GDB symtab. It takes these arguments and an implicit argument. - - TYPE is the type field of the ".stab" symbol entry. - DESC is the desc field of the ".stab" entry. - VALU is the value field of the ".stab" entry. - NAME is the symbol name, in our address space. - SECTION_OFFSETS is a set of amounts by which the sections of this object - file were relocated when it was loaded into memory. - All symbols that refer - to memory locations need to be offset by these amounts. - OBJFILE is the object file from which we are reading symbols. - It is used in end_symtab. */ - -void -process_one_symbol (type, desc, valu, name, section_offsets, objfile) - int type, desc; - CORE_ADDR valu; - char *name; - struct section_offsets *section_offsets; - struct objfile *objfile; -{ -#ifdef SUN_FIXED_LBRAC_BUG - /* If SUN_FIXED_LBRAC_BUG is defined, then it tells us whether we need - to correct the address of N_LBRAC's. If it is not defined, then - we never need to correct the addresses. */ - - /* This records the last pc address we've seen. We depend on there being - an SLINE or FUN or SO before the first LBRAC, since the variable does - not get reset in between reads of different symbol files. */ - static CORE_ADDR last_pc_address; -#endif - - register struct context_stack *new; - /* This remembers the address of the start of a function. It is used - because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries are - relative to the current function's start address. On systems - other than Solaris 2, this just holds the SECT_OFF_TEXT value, and is - used to relocate these symbol types rather than SECTION_OFFSETS. */ - static CORE_ADDR function_start_offset; - - /* If this is nonzero, we've seen a non-gcc N_OPT symbol for this source - file. Used to detect the SunPRO solaris compiler. */ - static int n_opt_found; - - /* The stab type used for the definition of the last function. - N_STSYM or N_GSYM for SunOS4 acc; N_FUN for other compilers. */ - static int function_stab_type = 0; - - if (!block_address_function_relative) - /* N_LBRAC, N_RBRAC and N_SLINE entries are not relative to the - function start address, so just use the text offset. */ - function_start_offset = ANOFFSET (section_offsets, SECT_OFF_TEXT); - - /* Something is wrong if we see real data before - 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)), - but this should not be an error (). */ - return; - } - - switch (type) - { - case N_FUN: - case N_FNAME: - /* Relocate for dynamic loading */ - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); - goto define_a_symbol; - - case N_LBRAC: - /* This "symbol" just indicates the start of an inner lexical - context within a function. */ - -#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; - else - /* 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) { - /* Patch current LBRAC pc value to match last handy pc value */ - complain (&lbrac_complaint); - valu = last_pc_address; - } -#endif - new = push_context (desc, valu); - break; - - case N_RBRAC: - /* This "symbol" just indicates the end of an inner lexical - context that was started with N_LBRAC. */ - -#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; - else - /* 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) - complain (&lbrac_mismatch_complaint, symnum); - - /* Some compilers put the variable decls inside of an - LBRAC/RBRAC block. This macro should be nonzero if this - is true. DESC is N_DESC from the N_RBRAC symbol. - GCC_P is true if we've detected the GCC_COMPILED_SYMBOL - or the GCC2_COMPILED_SYMBOL. */ -#if !defined (VARIABLES_INSIDE_BLOCK) -#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) 0 -#endif - - /* Can only use new->locals as local symbols here if we're in - gcc or on a machine that puts them before the lbrack. */ - if (!VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation)) - local_symbols = new->locals; - - if (context_stack_depth - > !VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation)) - { - /* This is not the outermost LBRAC...RBRAC pair in the function, - its local symbols preceded it, and are the ones just recovered - from the context stack. Define the block for them (but don't - bother if the block contains no symbols. Should we complain - on blocks without symbols? I can't think of any useful purpose - for them). */ - if (local_symbols != NULL) - { - /* Muzzle a compiler bug that makes end < start. (which - compilers? Is this ever harmful?). */ - if (new->start_addr > valu) - { - complain (&lbrac_rbrac_complaint); - new->start_addr = valu; - } - /* Make a block for the local symbols within. */ - finish_block (0, &local_symbols, new->old_blocks, - new->start_addr, valu, objfile); - } - } - else - { - /* This is the outermost LBRAC...RBRAC pair. There is no - need to do anything; leave the symbols that preceded it - to be attached to the function's own block. We need to - indicate that we just moved outside of the function. */ - within_function = 0; - } - - if (VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation)) - /* Now pop locals of block just finished. */ - local_symbols = new->locals; - break; - - case N_FN: - case N_FN_SEQ: - /* This kind of symbol indicates the start of an object file. */ - /* Relocate for dynamic loading */ - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); - break; - - case N_SO: - /* This type of symbol indicates the start of data - for one source file. - Finish the symbol table of the previous source file - (if any) and start accumulating a new symbol table. */ - /* Relocate for dynamic loading */ - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); - - n_opt_found = 0; - -#ifdef SUN_FIXED_LBRAC_BUG - last_pc_address = valu; /* Save for SunOS bug circumcision */ -#endif - -#ifdef PCC_SOL_BROKEN - /* pcc bug, occasionally puts out SO for SOL. */ - if (context_stack_depth > 0) - { - start_subfile (name, NULL); - break; - } -#endif - if (last_source_file) - { - /* Check if previous symbol was also an N_SO (with some - sanity checks). If so, that one was actually the directory - name, and the current one is the real file name. - Patch things up. */ - if (previous_stab_code == (unsigned char) N_SO) - { - patch_subfile_names (current_subfile, name); - break; /* Ignore repeated SOs */ - } - end_symtab (valu, 0, 0, objfile, SECT_OFF_TEXT); - end_stabs (); - } - - /* Null name means this just marks the end of text for this .o file. - Don't start a new symtab in this case. */ - if (*name == '\000') - break; - - start_stabs (); - start_symtab (name, NULL, valu); - break; - - case N_SOL: - /* This type of symbol indicates the start of data for - a sub-source-file, one whose contents were copied or - included in the compilation of the main source file - (whose name was given in the N_SO symbol.) */ - /* Relocate for dynamic loading */ - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); - start_subfile (name, current_subfile->dirname); - break; - - case N_BINCL: - push_subfile (); - add_new_header_file (name, valu); - start_subfile (name, current_subfile->dirname); - break; - - case N_EINCL: - start_subfile (pop_subfile (), current_subfile->dirname); - break; - - case N_EXCL: - add_old_header_file (name, valu); - break; - - case N_SLINE: - /* 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 - record_line (current_subfile, desc, valu); - break; - - case N_BCOMM: - common_block_start (name, objfile); - break; - - case N_ECOMM: - common_block_end (objfile); - break; - - /* The following symbol types need to have the appropriate offset added - to their value; then we process symbol definitions in the name. */ - - case N_STSYM: /* Static symbol in data seg */ - case N_LCSYM: /* Static symbol in BSS seg */ - case N_ROSYM: /* Static symbol in Read-only data seg */ - /* HORRID HACK DEPT. However, it's Sun's furgin' fault. - Solaris2's stabs-in-elf makes *most* symbols relative - but leaves a few absolute (at least for Solaris 2.1 and version - 2.0.1 of the SunPRO compiler). N_STSYM and friends sit on the fence. - .stab "foo:S...",N_STSYM is absolute (ld relocates it) - .stab "foo:V...",N_STSYM is relative (section base subtracted). - This leaves us no choice but to search for the 'S' or 'V'... - (or pass the whole section_offsets stuff down ONE MORE function - call level, which we really don't want to do). */ - { - char *p; - - /* .o files and NLMs have non-zero text seg offsets, but don't need - their static syms offset in this fashion. XXX - This is really a - crock that should be fixed in the solib handling code so that I - don't have to work around it here. */ - - if (!symfile_relocatable) - { - p = strchr (name, ':'); - if (p != 0 && p[1] == 'S') - { - /* The linker relocated it. We don't want to add an - elfstab_offset_sections-type offset, but we *do* want - to add whatever solib.c passed to symbol_file_add as - addr (this is known to affect SunOS4, and I suspect ELF - too). Since elfstab_offset_sections currently does not - muck with the text offset (there is no Ttext.text - symbol), we can get addr from the text offset. If - elfstab_offset_sections ever starts dealing with the - text offset, and we still need to do this, we need to - invent a SECT_OFF_ADDR_KLUDGE or something. */ - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); - goto define_a_symbol; - } - } - /* Since it's not the kludge case, re-dispatch to the right handler. */ - switch (type) { - case N_STSYM: goto case_N_STSYM; - case N_LCSYM: goto case_N_LCSYM; - case N_ROSYM: goto case_N_ROSYM; - default: abort(); - } - } - - case_N_STSYM: /* Static symbol in data seg */ - case N_DSLINE: /* Source line number, data seg */ - valu += ANOFFSET (section_offsets, SECT_OFF_DATA); - goto define_a_symbol; - - case_N_LCSYM: /* Static symbol in BSS seg */ - case N_BSLINE: /* Source line number, bss seg */ - /* N_BROWS: overlaps with N_BSLINE */ - valu += ANOFFSET (section_offsets, SECT_OFF_BSS); - goto define_a_symbol; - - case_N_ROSYM: /* Static symbol in Read-only data seg */ - valu += ANOFFSET (section_offsets, SECT_OFF_RODATA); - goto define_a_symbol; - - case N_ENTRY: /* Alternate entry point */ - /* Relocate for dynamic loading */ - valu += ANOFFSET (section_offsets, SECT_OFF_TEXT); - goto define_a_symbol; - - /* The following symbol types we don't know how to process. Handle - them in a "default" way, but complain to people who care. */ - default: - case N_CATCH: /* Exception handler catcher */ - case N_EHDECL: /* Exception handler name */ - case N_PC: /* Global symbol in Pascal */ - case N_M2C: /* Modula-2 compilation unit */ - /* N_MOD2: overlaps with N_EHDECL */ - case N_SCOPE: /* Modula-2 scope information */ - case N_ECOML: /* End common (local name) */ - case N_NBTEXT: /* Gould Non-Base-Register symbols??? */ - case N_NBDATA: - case N_NBBSS: - case N_NBSTS: - case N_NBLCS: - complain (&unknown_symtype_complaint, local_hex_string (type)); - /* FALLTHROUGH */ - - /* The following symbol types don't need the address field relocated, - since it is either unused, or is absolute. */ - define_a_symbol: - case N_GSYM: /* Global variable */ - case N_NSYMS: /* Number of symbols (ultrix) */ - case N_NOMAP: /* No map? (ultrix) */ - case N_RSYM: /* Register variable */ - case N_DEFD: /* Modula-2 GNU module dependency */ - case N_SSYM: /* Struct or union element */ - case N_LSYM: /* Local symbol in stack */ - case N_PSYM: /* Parameter variable */ - case N_LENG: /* Length of preceding symbol type */ - if (name) - { - int deftype; - char *colon_pos = strchr (name, ':'); - if (colon_pos == NULL) - deftype = '\0'; - else - deftype = colon_pos[1]; - - switch (deftype) - { - case 'f': - case 'F': - function_stab_type = type; - -#ifdef SUN_FIXED_LBRAC_BUG - /* The Sun acc compiler, under SunOS4, puts out - functions with N_GSYM or N_STSYM. The problem is - that the address of the symbol is no good (for N_GSYM - it doesn't even attept an address; for N_STSYM it - puts out an address but then it gets relocated - relative to the data segment, not the text segment). - Currently we can't fix this up later as we do for - some types of symbol in scan_file_globals. - Fortunately we do have a way of finding the address - - we know that the value in last_pc_address is either - the one we want (if we're dealing with the first - function in an object file), or somewhere in the - previous function. This means that we can use the - minimal symbol table to get the address. */ - - /* On solaris up to 2.2, the N_FUN stab gets relocated. - On Solaris 2.3, ld no longer relocates stabs (which - is good), and the N_FUN's value is now always zero. - The following code can't deal with this, because - last_pc_address depends on getting the address from a - N_SLINE or some such and in Solaris those are function - relative. Best fix is probably to create a Ttext.text symbol - and handle this like Ddata.data and so on. */ - - if (type == N_GSYM || type == N_STSYM) - { - struct minimal_symbol *m; - int l = colon_pos - name; - - m = lookup_minimal_symbol_by_pc (last_pc_address); - if (m && STREQN (SYMBOL_NAME (m), name, l)) - /* last_pc_address was in this function */ - valu = SYMBOL_VALUE (m); - else if (m && STREQN (SYMBOL_NAME (m+1), name, l)) - /* last_pc_address was in last function */ - valu = SYMBOL_VALUE (m+1); - else - /* Not found - use last_pc_address (for finish_block) */ - valu = last_pc_address; - } - - last_pc_address = valu; /* Save for SunOS bug circumcision */ -#endif - - if (block_address_function_relative) - /* For Solaris 2.0 compilers, the block addresses and - N_SLINE's are relative to the start of the - function. On normal systems, and when using gcc on - Solaris 2.0, these addresses are just absolute, or - relative to the N_SO, depending on - BLOCK_ADDRESS_ABSOLUTE. */ - function_start_offset = valu; - - within_function = 1; - if (context_stack_depth > 0) - { - 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); - } - /* Stack must be empty now. */ - if (context_stack_depth != 0) - complain (&lbrac_unmatched_complaint, symnum); - - new = push_context (0, valu); - new->name = define_symbol (valu, name, desc, type, objfile); - break; - - default: - define_symbol (valu, name, desc, type, objfile); - break; - } - } - break; - - /* We use N_OPT to carry the gcc2_compiled flag. Sun uses it - for a bunch of other flags, too. Someday we may parse their - flags; for now we ignore theirs and hope they'll ignore ours. */ - case N_OPT: /* Solaris 2: Compiler options */ - if (name) - { - if (STREQ (name, GCC2_COMPILED_FLAG_SYMBOL)) - { - processing_gcc_compilation = 2; -#if 1 /* Works, but is experimental. -fnf */ - if (AUTO_DEMANGLING) - { - set_demangling_style (GNU_DEMANGLING_STYLE_STRING); - } -#endif - } - else - n_opt_found = 1; - } - break; - - /* The following symbol types can be ignored. */ - case N_OBJ: /* Solaris 2: Object file dir and name */ - /* N_UNDF: Solaris 2: file separator mark */ - /* N_UNDF: -- we will never encounter it, since we only process one - file's symbols at once. */ - case N_ENDM: /* Solaris 2: End of module */ - case N_MAIN: /* Name of main routine. */ - break; - } - - previous_stab_code = type; -} - -/* FIXME: The only difference between this and elfstab_build_psymtabs is - the call to install_minimal_symbols for elf. If the differences are - really that small, the code should be shared. */ - -/* Scan and build partial symbols for an coff symbol file. - The coff file has already been processed to get its minimal symbols. - - This routine is the equivalent of dbx_symfile_init and dbx_symfile_read - rolled into one. - - OBJFILE is the object file we are reading symbols from. - ADDR is the address relative to which the symbols are (e.g. - the base address of the text segment). - MAINLINE is true if we are reading the main symbol - table (as opposed to a shared lib or dynamically loaded file). - STABOFFSET and STABSIZE define the location in OBJFILE where the .stab - section exists. - STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the - .stabstr section exists. - - This routine is mostly copied from dbx_symfile_init and dbx_symfile_read, - adjusted for coff details. */ - -void -coffstab_build_psymtabs (objfile, section_offsets, mainline, - staboffset, stabsize, - stabstroffset, stabstrsize) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; - file_ptr staboffset; - unsigned int stabsize; - file_ptr stabstroffset; - unsigned int stabstrsize; -{ - int val; - bfd *sym_bfd = objfile->obfd; - char *name = bfd_get_filename (sym_bfd); - struct dbx_symfile_info *info; - - /* 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; - - DBX_TEXT_SECT (objfile) = bfd_get_section_by_name (sym_bfd, ".text"); - if (!DBX_TEXT_SECT (objfile)) - error ("Can't find .text section in symbol file"); - -#define COFF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */ - DBX_SYMBOL_SIZE (objfile) = COFF_STABS_SYMBOL_SIZE; - DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile); - DBX_STRINGTAB_SIZE (objfile) = stabstrsize; - DBX_SYMTAB_OFFSET (objfile) = staboffset; - - if (stabstrsize > bfd_get_size (sym_bfd)) - error ("ridiculous string table size: %d bytes", stabstrsize); - DBX_STRINGTAB (objfile) = (char *) - obstack_alloc (&objfile->psymbol_obstack, stabstrsize+1); - - /* Now read in the string table in one big gulp. */ - - val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET); - if (val < 0) - perror_with_name (name); - val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, 1, sym_bfd); - if (val != stabstrsize) - perror_with_name (name); - - stabsread_new_init (); - buildsym_new_init (); - free_header_files (); - init_header_files (); - - processing_acc_compilation = 1; - - /* In a coff file, we've already installed the minimal symbols that came - from the coff (non-stab) symbol table, so always act like an - incremental load here. */ - dbx_symfile_read (objfile, section_offsets, 0); -} - -/* Scan and build partial symbols for an ELF symbol file. - This ELF file has already been processed to get its minimal symbols, - and any DWARF symbols that were in it. - - This routine is the equivalent of dbx_symfile_init and dbx_symfile_read - rolled into one. - - OBJFILE is the object file we are reading symbols from. - ADDR is the address relative to which the symbols are (e.g. - the base address of the text segment). - MAINLINE is true if we are reading the main symbol - table (as opposed to a shared lib or dynamically loaded file). - STABOFFSET and STABSIZE define the location in OBJFILE where the .stab - section exists. - STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the - .stabstr section exists. - - This routine is mostly copied from dbx_symfile_init and dbx_symfile_read, - adjusted for elf details. */ - -void -elfstab_build_psymtabs (objfile, section_offsets, mainline, - staboffset, stabsize, - stabstroffset, stabstrsize) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; - file_ptr staboffset; - unsigned int stabsize; - file_ptr stabstroffset; - unsigned int stabstrsize; -{ - int val; - bfd *sym_bfd = objfile->obfd; - char *name = bfd_get_filename (sym_bfd); - struct dbx_symfile_info *info; - - /* 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; - - DBX_TEXT_SECT (objfile) = bfd_get_section_by_name (sym_bfd, ".text"); - if (!DBX_TEXT_SECT (objfile)) - error ("Can't find .text section in symbol file"); - -#define ELF_STABS_SYMBOL_SIZE 12 /* XXX FIXME XXX */ - DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE; - DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile); - DBX_STRINGTAB_SIZE (objfile) = stabstrsize; - DBX_SYMTAB_OFFSET (objfile) = staboffset; - - if (stabstrsize > bfd_get_size (sym_bfd)) - error ("ridiculous string table size: %d bytes", stabstrsize); - DBX_STRINGTAB (objfile) = (char *) - obstack_alloc (&objfile->psymbol_obstack, stabstrsize+1); - - /* Now read in the string table in one big gulp. */ - - val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET); - if (val < 0) - perror_with_name (name); - val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, 1, sym_bfd); - if (val != stabstrsize) - perror_with_name (name); - - stabsread_new_init (); - buildsym_new_init (); - free_header_files (); - init_header_files (); - install_minimal_symbols (objfile); - - processing_acc_compilation = 1; - - /* In an elf file, we've already installed the minimal symbols that came - from the elf (non-stab) symbol table, so always act like an - incremental load here. */ - dbx_symfile_read (objfile, section_offsets, 0); -} - -/* Scan and build partial symbols for a file with special sections for stabs - and stabstrings. The file has already been processed to get its minimal - symbols, and any other symbols that might be necessary to resolve GSYMs. - - This routine is the equivalent of dbx_symfile_init and dbx_symfile_read - rolled into one. - - OBJFILE is the object file we are reading symbols from. - ADDR is the address relative to which the symbols are (e.g. the base address - of the text segment). - MAINLINE is true if we are reading the main symbol table (as opposed to a - shared lib or dynamically loaded file). - STAB_NAME is the name of the section that contains the stabs. - STABSTR_NAME is the name of the section that contains the stab strings. - - This routine is mostly copied from dbx_symfile_init and dbx_symfile_read. */ - -void -stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name, - stabstr_name, text_name) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; - char *stab_name; - char *stabstr_name; - char *text_name; -{ - int val; - bfd *sym_bfd = objfile->obfd; - char *name = bfd_get_filename (sym_bfd); - asection *stabsect; - asection *stabstrsect; - - stabsect = bfd_get_section_by_name (sym_bfd, stab_name); - stabstrsect = bfd_get_section_by_name (sym_bfd, stabstr_name); - - if (!stabsect) - return; - - if (!stabstrsect) - 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)); - - DBX_TEXT_SECT (objfile) = bfd_get_section_by_name (sym_bfd, text_name); - if (!DBX_TEXT_SECT (objfile)) - error ("Can't find %s section in symbol file", text_name); - - DBX_SYMBOL_SIZE (objfile) = sizeof (struct external_nlist); - DBX_SYMCOUNT (objfile) = bfd_section_size (sym_bfd, stabsect) - / DBX_SYMBOL_SIZE (objfile); - DBX_STRINGTAB_SIZE (objfile) = bfd_section_size (sym_bfd, stabstrsect); - DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos; /* XXX - FIXME: POKING INSIDE BFD DATA STRUCTURES */ - - if (DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd)) - error ("ridiculous string table size: %d bytes", DBX_STRINGTAB_SIZE (objfile)); - DBX_STRINGTAB (objfile) = (char *) - obstack_alloc (&objfile->psymbol_obstack, DBX_STRINGTAB_SIZE (objfile) + 1); - - /* Now read in the string table in one big gulp. */ - - val = bfd_get_section_contents (sym_bfd, /* bfd */ - stabstrsect, /* bfd section */ - DBX_STRINGTAB (objfile), /* input buffer */ - 0, /* offset into section */ - DBX_STRINGTAB_SIZE (objfile)); /* amount to read */ - - if (!val) - perror_with_name (name); - - stabsread_new_init (); - buildsym_new_init (); - free_header_files (); - init_header_files (); - install_minimal_symbols (objfile); - - /* Now, do an incremental load */ - - processing_acc_compilation = 1; - 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, - dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */ - 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 */ - NULL /* next: pointer to next struct sym_fns */ -}; - -void -_initialize_dbxread () -{ - add_symtab_fns(&aout_sym_fns); -} diff --git a/gnu/usr.bin/gdb/gdb/dcache.c b/gnu/usr.bin/gdb/gdb/dcache.c deleted file mode 100644 index a957abe..0000000 --- a/gnu/usr.bin/gdb/gdb/dcache.c +++ /dev/null @@ -1,236 +0,0 @@ -/* Caching code. Typically used by remote back ends for - caching remote memory. - - Copyright 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. */ - -#include "defs.h" -#include "dcache.h" -#include "gdbcmd.h" - -extern int insque(); -extern int remque(); - -int remote_dcache = 0; - -/* The data cache records all the data read from the remote machine - since the last time it stopped. - - Each cache block holds LINE_SIZE bytes of data - starting at a multiple-of-LINE_SIZE address. */ - -#define LINE_SIZE_MASK ((LINE_SIZE - 1)) /* eg 7*2+1= 111*/ -#define XFORM(x) (((x) & LINE_SIZE_MASK) >> 2) - -/* Free all the data cache blocks, thus discarding all cached data. */ -void -dcache_flush (dcache) - DCACHE *dcache; -{ - register struct dcache_block *db; - - if (remote_dcache > 0) - while ((db = dcache->dcache_valid.next) != &dcache->dcache_valid) - { - remque (db); - insque (db, &dcache->dcache_free); - } - - return; -} - -/* - * If addr is present in the dcache, return the address of the block - * containing it. - */ -static -struct dcache_block * -dcache_hit (dcache, addr) - DCACHE *dcache; - unsigned int addr; -{ - register struct dcache_block *db; - - if (addr & 3 - || remote_dcache == 0) - abort (); - - /* Search all cache blocks for one that is at this address. */ - db = dcache->dcache_valid.next; - while (db != &dcache->dcache_valid) - { - if ((addr & ~LINE_SIZE_MASK) == db->addr) - return db; - db = db->next; - } - - return NULL; -} - -/* Return the int data at address ADDR in dcache block DC. */ -static -int -dcache_value (db, addr) - struct dcache_block *db; - unsigned int addr; -{ - if (addr & 3 - || remote_dcache == 0) - abort (); - return (db->data[XFORM (addr)]); -} - -/* Get a free cache block, put or keep it on the valid list, - and return its address. The caller should store into the block - the address and data that it describes, then remque it from the - free list and insert it into the valid list. This procedure - 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 * -dcache_alloc (dcache) - DCACHE *dcache; -{ - register struct dcache_block *db; - - if (remote_dcache == 0) - abort(); - - if ((db = dcache->dcache_free.next) == &dcache->dcache_free) - { - /* If we can't get one from the free list, take last valid and put - it on the free list. */ - db = dcache->dcache_valid.last; - remque (db); - insque (db, &dcache->dcache_free); - } - - remque (db); - insque (db, &dcache->dcache_valid); - return (db); -} - -/* Using the data cache DCACHE return the contents of the word at - address ADDR in the remote machine. */ -int -dcache_fetch (dcache, addr) - DCACHE *dcache; - CORE_ADDR addr; -{ - register struct dcache_block *db; - - if (remote_dcache == 0) - { - int i; - - (*dcache->read_memory) (addr, (unsigned char *) &i, 4); - return(i); - } - - db = dcache_hit (dcache, addr); - if (db == 0) - { - db = dcache_alloc (dcache); - immediate_quit++; - (*dcache->read_memory) (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE); - immediate_quit--; - db->addr = addr & ~LINE_SIZE_MASK; - remque (db); /* Off the free list */ - insque (db, &dcache->dcache_valid); /* On the valid list */ - } - return (dcache_value (db, addr)); -} - -/* Write the word at ADDR both in the data cache and in the remote machine. */ -void -dcache_poke (dcache, addr, data) - DCACHE *dcache; - CORE_ADDR addr; - int data; -{ - register struct dcache_block *db; - - if (remote_dcache == 0) - { - (*dcache->write_memory) (addr, (unsigned char *) &data, 4); - return; - } - - /* First make sure the word is IN the cache. DB is its cache block. */ - db = dcache_hit (dcache, addr); - if (db == 0) - { - db = dcache_alloc (dcache); - immediate_quit++; - (*dcache->write_memory) (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE); - immediate_quit--; - db->addr = addr & ~LINE_SIZE_MASK; - remque (db); /* Off the free list */ - insque (db, &dcache->dcache_valid); /* On the valid list */ - } - - /* Modify the word in the cache. */ - db->data[XFORM (addr)] = data; - - /* Send the changed word. */ - immediate_quit++; - (*dcache->write_memory) (addr, (unsigned char *) &data, 4); - immediate_quit--; -} - -/* Initialize the data cache. */ -DCACHE * -dcache_init (reading, writing) - memxferfunc reading; - memxferfunc writing; -{ - register i; - register struct dcache_block *db; - DCACHE *dcache; - - dcache = (DCACHE *) xmalloc (sizeof (*dcache)); - dcache->read_memory = reading; - dcache->write_memory = writing; - dcache->the_cache = (struct dcache_block *) - xmalloc (sizeof (*dcache->the_cache) * DCACHE_SIZE); - - dcache->dcache_free.next = dcache->dcache_free.last = &dcache->dcache_free; - dcache->dcache_valid.next = dcache->dcache_valid.last = &dcache->dcache_valid; - for (db = dcache->the_cache, i = 0; i < DCACHE_SIZE; i++, db++) - insque (db, &dcache->dcache_free); - - return(dcache); -} - -void -_initialitize_dcache () -{ - add_show_from_set - (add_set_cmd ("remotecache", class_support, var_boolean, - (char *) &remote_dcache, - "\ -Set cache use for remote targets.\n\ -When on, use data caching for remote targets. For many remote targets\n\ -this option can offer better throughput for reading target memory.\n\ -Unfortunately, gdb does not currently know anything about volatile\n\ -registers and thus data caching will produce incorrect results with\n\ -volatile registers are in use. By default, this option is off.", - &setlist), - &showlist); -} diff --git a/gnu/usr.bin/gdb/gdb/dcache.h b/gnu/usr.bin/gdb/gdb/dcache.h deleted file mode 100644 index bfc0dd7..0000000 --- a/gnu/usr.bin/gdb/gdb/dcache.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Declarations for caching. Typically used by remote back ends for - caching remote memory. - - Copyright 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. */ - -#ifndef DCACHE_H -#define DCACHE_H - -/* The data cache leads to incorrect results because it doesn't know about - volatile variables, thus making it impossible to debug functions which - use hardware registers. Therefore it is #if 0'd out. Effect on - performance is some, for backtraces of functions with a few - arguments each. For functions with many arguments, the stack - frames don't fit in the cache blocks, which makes the cache less - helpful. Disabling the cache is a big performance win for fetching - large structures, because the cache code fetched data in 16-byte - chunks. */ - -#define LINE_SIZE_POWER (4) -/* eg 1<<3 == 8 */ -#define LINE_SIZE (1 << LINE_SIZE_POWER) -/* Number of cache blocks */ -#define DCACHE_SIZE (64) - -struct dcache_block -{ - struct dcache_block *next, *last; - unsigned int addr; /* Address for which data is recorded. */ - int data[LINE_SIZE / sizeof (int)]; -}; - -typedef int (*memxferfunc) PARAMS((CORE_ADDR memaddr, - unsigned char *myaddr, - int len)); - -typedef struct { - /* Function to actually read the target memory. */ - memxferfunc read_memory; - - /* Function to actually write the target memory */ - memxferfunc write_memory; - - /* free list */ - struct dcache_block dcache_free; - - /* in use list */ - struct dcache_block dcache_valid; - - /* The cache itself. */ - struct dcache_block *the_cache; - -} DCACHE; - -/* Using the data cache DCACHE return the contents of the word at - address ADDR in the remote machine. */ -int dcache_fetch PARAMS((DCACHE *dcache, CORE_ADDR addr)); - -/* Flush DCACHE. */ -void dcache_flush PARAMS((DCACHE *dcache)); - -/* Initialize DCACHE. */ -DCACHE *dcache_init PARAMS((memxferfunc reading, memxferfunc writing)); - -/* Write the word at ADDR both in the data cache and in the remote machine. */ -void dcache_poke PARAMS((DCACHE *dcache, CORE_ADDR addr, int data)); - -#endif /* DCACHE_H */ diff --git a/gnu/usr.bin/gdb/gdb/defs.h b/gnu/usr.bin/gdb/gdb/defs.h deleted file mode 100644 index cb95cae..0000000 --- a/gnu/usr.bin/gdb/gdb/defs.h +++ /dev/null @@ -1,947 +0,0 @@ -/* Basic, host-specific, and target-specific definitions for GDB. - Copyright (C) 1986, 1989, 1991 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 (DEFS_H) -#define DEFS_H 1 - -#include - -/* First include ansidecl.h so we can use the various macro definitions - here and in all subsequent file inclusions. */ - -#include "ansidecl.h" - -/* For BFD64 and bfd_vma. */ -#include "bfd.h" - -/* An address in the program being debugged. Host byte order. Rather - than duplicate all the logic in BFD which figures out what type - this is (long, long long, etc.) and whether it needs to be 64 - bits (the host/target interactions are subtle), we just use - bfd_vma. */ - -typedef bfd_vma CORE_ADDR; - -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) > (b) ? (a) : (b)) - -/* Gdb does *lots* of string compares. Use macros to speed them up by - avoiding function calls if the first characters are not the same. */ - -#define STRCMP(a,b) (*(a) == *(b) ? strcmp ((a), (b)) : (int)*(a) - (int)*(b)) -#define STREQ(a,b) (*(a) == *(b) ? !strcmp ((a), (b)) : 0) -#define STREQN(a,b,c) (*(a) == *(b) ? !strncmp ((a), (b), (c)) : 0) - -/* The character GNU C++ uses to build identifiers that must be unique from - the program's identifiers (such as $this and $$vptr). */ -#define CPLUS_MARKER '$' /* May be overridden to '.' for SysV */ - -#include /* System call error return status */ - -extern int quit_flag; -extern int immediate_quit; -extern int sevenbit_strings; - -extern void -quit PARAMS ((void)); - -#define QUIT { if (quit_flag) quit (); } - -/* Command classes are top-level categories into which commands are broken - down for "help" purposes. - Notes on classes: class_alias is for alias commands which are not - abbreviations of the original command. class-pseudo is for commands - which are not really commands nor help topics ("stop"). */ - -enum command_class -{ - /* Special args to help_list */ - 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_alias, class_obscure, class_user, class_maintenance, - class_pseudo -}; - -/* Languages represented in the symbol table and elsewhere. - This should probably be in language.h, but since enum's can't - be forward declared to satisfy opaque references before their - actual definition, needs to be here. */ - -enum language -{ - language_unknown, /* Language not known */ - language_auto, /* Placeholder for automatic setting */ - language_c, /* C */ - language_cplus, /* C++ */ - language_chill, /* Chill */ - language_m2, /* Modula-2 */ - language_asm /* Assembly language */ -}; - -/* 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 - argument to give it. - - Use make_cleanup to add an element to the cleanup chain. - Use do_cleanups to do all cleanup actions back to a given - point in the chain. Use discard_cleanups to remove cleanups - from the chain back to a given point, not doing them. */ - -struct cleanup -{ - struct cleanup *next; - void (*function) PARAMS ((PTR)); - PTR arg; -}; - -/* From blockframe.c */ - -extern int -inside_entry_func PARAMS ((CORE_ADDR)); - -extern int -inside_entry_file PARAMS ((CORE_ADDR addr)); - -extern int -inside_main_func PARAMS ((CORE_ADDR pc)); - -/* From ch-lang.c, for the moment. (FIXME) */ - -extern char * -chill_demangle PARAMS ((const char *)); - -/* From libiberty.a */ - -extern char * -cplus_demangle PARAMS ((const char *, int)); - -extern char * -cplus_mangle_opname PARAMS ((char *, int)); - -/* From libmmalloc.a (memory mapped malloc library) */ - -extern PTR -mmalloc_attach PARAMS ((int, PTR)); - -extern PTR -mmalloc_detach PARAMS ((PTR)); - -extern PTR -mmalloc PARAMS ((PTR, long)); - -extern PTR -mrealloc PARAMS ((PTR, PTR, long)); - -extern void -mfree PARAMS ((PTR, PTR)); - -extern int -mmalloc_setkey PARAMS ((PTR, int, PTR)); - -extern PTR -mmalloc_getkey PARAMS ((PTR, int)); - -/* From utils.c */ - -extern int -strcmp_iw PARAMS ((const char *, const char *)); - -extern char * -safe_strerror PARAMS ((int)); - -extern char * -safe_strsignal PARAMS ((int)); - -extern void -init_malloc PARAMS ((void *)); - -extern void -request_quit PARAMS ((int)); - -extern void -do_cleanups PARAMS ((struct cleanup *)); - -extern void -discard_cleanups PARAMS ((struct cleanup *)); - -/* 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. - - Should be, once all calls and called-functions are cleaned up: -extern struct cleanup * -make_cleanup PARAMS ((void (*function) (void *), 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_cleanup (); - -extern struct cleanup * -save_cleanups PARAMS ((void)); - -extern void -restore_cleanups PARAMS ((struct cleanup *)); - -extern void -free_current_contents PARAMS ((char **)); - -extern void -null_cleanup PARAMS ((char **)); - -extern int -myread PARAMS ((int, char *, int)); - -extern int -query (); - -/* Annotation stuff. */ - -extern int annotation_level; /* in stack.c */ - -extern void -begin_line PARAMS ((void)); - -extern void -wrap_here PARAMS ((char *)); - -extern void -reinitialize_more_filter PARAMS ((void)); - -typedef FILE GDB_FILE; -#define gdb_stdout stdout -#define gdb_stderr stderr - -extern int -print_insn PARAMS ((CORE_ADDR, GDB_FILE *)); - -extern void -gdb_flush PARAMS ((GDB_FILE *)); - -extern GDB_FILE * -gdb_fopen PARAMS ((char * name, char * mode)); - -extern void -fputs_filtered PARAMS ((const char *, GDB_FILE *)); - -extern void -fputs_unfiltered PARAMS ((const char *, GDB_FILE *)); - -extern void -fputc_unfiltered PARAMS ((int, GDB_FILE *)); - -extern void -putc_unfiltered PARAMS ((int)); - -#define putchar_unfiltered(C) putc_unfiltered(C) - -extern void -puts_filtered PARAMS ((char *)); - -extern void -puts_unfiltered PARAMS ((char *)); - -extern void -vprintf_filtered (); - -extern void -vfprintf_filtered (); - -extern void -fprintf_filtered (); - -extern void -fprintfi_filtered (); - -extern void -printf_filtered (); - -extern void -printfi_filtered (); - -extern void -vprintf_unfiltered (); - -extern void -vfprintf_unfiltered (); - -extern void -fprintf_unfiltered (); - -extern void -printf_unfiltered (); - -extern void -print_spaces PARAMS ((int, GDB_FILE *)); - -extern void -print_spaces_filtered PARAMS ((int, GDB_FILE *)); - -extern char * -n_spaces PARAMS ((int)); - -extern void -gdb_printchar PARAMS ((int, GDB_FILE *, int)); - -/* Print a host address. */ -extern void gdb_print_address PARAMS ((void *, GDB_FILE *)); - -extern void -fprintf_symbol_filtered PARAMS ((GDB_FILE *, char *, enum language, int)); - -extern void -perror_with_name PARAMS ((char *)); - -extern void -print_sys_errmsg PARAMS ((char *, int)); - -/* From regex.c or libc. BSD 4.4 declares this with the argument type as - "const char *" in unistd.h, so we can't declare the argument - as "char *". */ - -extern char * -re_comp PARAMS ((const char *)); - -/* From symfile.c */ - -extern void -symbol_file_command PARAMS ((char *, int)); - -/* From main.c */ - -extern char * -skip_quoted PARAMS ((char *)); - -extern char * -gdb_readline PARAMS ((char *)); - -extern char * -command_line_input PARAMS ((char *, int, char *)); - -extern void -print_prompt PARAMS ((void)); - -extern int -input_from_terminal_p PARAMS ((void)); - -/* From printcmd.c */ - -extern void -set_next_address PARAMS ((CORE_ADDR)); - -extern void -print_address_symbolic PARAMS ((CORE_ADDR, GDB_FILE *, int, char *)); - -extern void -print_address_numeric PARAMS ((CORE_ADDR, int, GDB_FILE *)); - -extern void -print_address PARAMS ((CORE_ADDR, GDB_FILE *)); - -/* From source.c */ - -extern int -openp PARAMS ((char *, int, char *, int, int, char **)); - -extern void -mod_path PARAMS ((char *, char **)); - -extern void -directory_command PARAMS ((char *, int)); - -extern void -init_source_path PARAMS ((void)); - -/* From findvar.c */ - -extern int -read_relative_register_raw_bytes PARAMS ((int, char *)); - -/* From readline (but not in any readline .h files). */ - -extern char * -tilde_expand PARAMS ((char *)); - -/* Structure for saved commands lines - (for breakpoints, defined commands, etc). */ - -struct command_line -{ - struct command_line *next; - char *line; -}; - -extern struct command_line * -read_command_lines PARAMS ((void)); - -extern void -free_command_lines PARAMS ((struct command_line **)); - -/* String containing the current directory (what getwd would return). */ - -extern char *current_directory; - -/* Default radixes for input and output. Only some values supported. */ -extern unsigned input_radix; -extern unsigned output_radix; - -/* Possibilities for prettyprint parameters to routines which print - things. Like enum language, this should be in value.h, but needs - to be here for the same reason. FIXME: If we can eliminate this - as an arg to LA_VAL_PRINT, then we can probably move it back to - value.h. */ - -enum val_prettyprint -{ - Val_no_prettyprint = 0, - Val_prettyprint, - /* Use the default setting which the user has specified. */ - Val_pretty_default -}; - - -/* Host machine definition. This will be a symlink to one of the - xm-*.h files, built by the `configure' script. */ - -#include "xm.h" - -/* Native machine support. This will be a symlink to one of the - nm-*.h files, built by the `configure' script. */ - -#include "nm.h" - -#ifdef KERNEL_DEBUG -extern int kernel_debugging; -extern int kernel_writablecore; -#endif - -/* If the xm.h file did not define the mode string used to open the - files, assume that binary files are opened the same way as text - files */ -#ifndef FOPEN_RB -#include "fopen-same.h" -#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 - * 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__ -# define volatile __volatile__ -# else -# define volatile /*nothing*/ -# endif /* GNUC */ -#endif /* STDC */ -#endif /* volatile */ - -#if 1 -#define NORETURN /*nothing*/ -#else /* not 1 */ -/* FIXME: This is bogus. Having "volatile void" mean a function doesn't - return is a gcc extension and should be based on #ifdef __GNUC__. - Also, as of Sep 93 I'm told gcc is changing the syntax for ansi - reasons (so declaring exit here as "volatile void" and as "void" in - a system header loses). Using the new "__attributes__ ((noreturn));" - syntax would lose for old versions of gcc; using - typedef void exit_fn_type PARAMS ((int)); - volatile exit_fn_type exit; - would win. */ -/* Some compilers (many AT&T SVR4 compilers for instance), do not accept - declarations of functions that never return (exit for instance) as - "volatile void". For such compilers "NORETURN" can be defined away - to keep them happy */ - -#ifndef NORETURN -# ifdef __lucid -# define NORETURN /*nothing*/ -# else -# define NORETURN volatile -# endif -#endif -#endif /* not 1 */ - -/* Defaults for system-wide constants (if not defined by xm.h, we fake it). */ - -#if !defined (UINT_MAX) -#define UINT_MAX ((unsigned int)(~0)) /* 0xFFFFFFFF for 32-bits */ -#endif - -#if !defined (INT_MAX) -#define INT_MAX ((int)(UINT_MAX >> 1)) /* 0x7FFFFFFF for 32-bits */ -#endif - -#if !defined (INT_MIN) -#define INT_MIN (-INT_MAX - 1) /* 0x80000000 for 32-bits */ -#endif - -#if !defined (ULONG_MAX) -#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF for 32-bits */ -#endif - -#if !defined (LONG_MAX) -#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF for 32-bits */ -#endif - -#ifdef BFD64 - -/* This is to make sure that LONGEST is at least as big as CORE_ADDR. */ - -#define LONGEST BFD_HOST_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 -# else -# define LONGEST long -# endif -#endif - -#endif /* No BFD64 */ - -/* 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. */ - -extern int longest_to_int PARAMS ((LONGEST)); - -/* Assorted functions we can declare, now that const and volatile are - defined. */ - -extern char * -savestring PARAMS ((const char *, int)); - -extern char * -msavestring PARAMS ((void *, const char *, int)); - -extern char * -strsave PARAMS ((const char *)); - -extern char * -mstrsave PARAMS ((void *, const char *)); - -extern char * -concat PARAMS ((char *, ...)); - -extern PTR -xmalloc PARAMS ((long)); - -extern PTR -xrealloc PARAMS ((PTR, long)); - -extern PTR -xmmalloc PARAMS ((PTR, long)); - -extern PTR -xmrealloc PARAMS ((PTR, PTR, long)); - -extern PTR -mmalloc PARAMS ((PTR, long)); - -extern PTR -mrealloc PARAMS ((PTR, PTR, long)); - -extern void -mfree PARAMS ((PTR, PTR)); - -extern int -mmcheck PARAMS ((PTR, void (*) (void))); - -extern int -mmtrace PARAMS ((void)); - -extern int -parse_escape PARAMS ((char **)); - -extern const char * const reg_names[]; - -/* Message to be printed before the error message, when an error occurs. */ - -extern char *error_pre_print; - -/* Message to be printed before the warning message, when a warning occurs. */ - -extern char *warning_pre_print; - -extern NORETURN void /* Does not return to the caller. */ -error (); - -extern void error_begin PARAMS ((void)); - -extern NORETURN void /* Does not return to the caller. */ -fatal (); - -extern NORETURN void /* Not specified as volatile in ... */ -exit PARAMS ((int)); /* 4.10.4.3 */ - -extern NORETURN void /* Does not return to the caller. */ -nomem PARAMS ((long)); - -/* Reasons for calling return_to_top_level. */ -enum return_reason { - /* User interrupt. */ - RETURN_QUIT, - - /* Any other error. */ - RETURN_ERROR -}; - -#define RETURN_MASK_QUIT (1 << (int)RETURN_QUIT) -#define RETURN_MASK_ERROR (1 << (int)RETURN_ERROR) -#define RETURN_MASK_ALL (RETURN_MASK_QUIT | RETURN_MASK_ERROR) -typedef int return_mask; - -extern NORETURN void /* Does not return to the caller. */ -return_to_top_level PARAMS ((enum return_reason)); - -extern int catch_errors PARAMS ((int (*) (char *), void *, char *, - return_mask)); - -extern void -warning_setup PARAMS ((void)); - -extern void -warning (); - -/* Global functions from other, non-gdb GNU thingies (libiberty for - instance) */ - -extern char * -basename PARAMS ((char *)); - -extern char * -getenv PARAMS ((const char *)); - -extern char ** -buildargv PARAMS ((char *)); - -extern void -freeargv PARAMS ((char **)); - -extern char * -strerrno PARAMS ((int)); - -extern char * -strsigno PARAMS ((int)); - -extern int -errno_max PARAMS ((void)); - -extern int -signo_max PARAMS ((void)); - -extern int -strtoerrno PARAMS ((char *)); - -extern int -strtosigno PARAMS ((char *)); - -extern char * -strsignal PARAMS ((int)); - -/* From other system libraries */ - -#ifndef PSIGNAL_IN_SIGNAL_H -extern void -psignal PARAMS ((unsigned, const char *)); -#endif - -/* For now, we can't include because it conflicts with - "../include/getopt.h". (FIXME) - - However, if a function is defined in the ANSI C standard and a prototype - for that function is defined and visible in any header file in an ANSI - conforming environment, then that prototype must match the definition in - the ANSI standard. So we can just duplicate them here without conflict, - since they must be the same in all conforming ANSI environments. If - these cause problems, then the environment is not ANSI conformant. */ - -#ifdef __STDC__ -#include -#endif - -extern int -fclose PARAMS ((GDB_FILE *stream)); /* 4.9.5.1 */ - -extern void -perror PARAMS ((const char *)); /* 4.9.10.4 */ - -extern double -atof PARAMS ((const char *nptr)); /* 4.10.1.1 */ - -extern int -atoi PARAMS ((const char *)); /* 4.10.1.2 */ - -#ifndef MALLOC_INCOMPATIBLE - -extern PTR -malloc PARAMS ((size_t size)); /* 4.10.3.3 */ - -extern PTR -realloc PARAMS ((void *ptr, size_t size)); /* 4.10.3.4 */ - -extern void -free PARAMS ((void *)); /* 4.10.3.2 */ - -#endif /* MALLOC_INCOMPATIBLE */ - -extern void -qsort PARAMS ((void *base, size_t nmemb, /* 4.10.5.2 */ - size_t size, - int (*compar)(const void *, const void *))); - -#ifndef MEM_FNS_DECLARED /* Some non-ANSI use void *, not char *. */ -extern PTR -memcpy PARAMS ((void *, const void *, size_t)); /* 4.11.2.1 */ - -extern int -memcmp PARAMS ((const void *, const void *, size_t)); /* 4.11.4.1 */ -#endif - -extern char * -strchr PARAMS ((const char *, int)); /* 4.11.5.2 */ - -extern char * -strrchr PARAMS ((const char *, int)); /* 4.11.5.5 */ - -extern char * -strstr PARAMS ((const char *, const char *)); /* 4.11.5.7 */ - -extern char * -strtok PARAMS ((char *, const char *)); /* 4.11.5.8 */ - -#ifndef MEM_FNS_DECLARED /* Some non-ANSI use void *, not char *. */ -extern PTR -memset PARAMS ((void *, int, size_t)); /* 4.11.6.1 */ -#endif - -extern char * -strerror PARAMS ((int)); /* 4.11.6.2 */ - -/* Various possibilities for alloca. */ -#ifndef alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# else /* Not GNU C */ -# ifdef sparc -# include /* NOTE: Doesn't declare alloca() */ -# endif - -/* 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) - extern void *alloca (); -# else /* Don't use void *. */ - extern char *alloca (); -# endif /* Don't use void *. */ -# endif /* Not GNU C */ -#endif /* alloca not defined */ - -/* TARGET_BYTE_ORDER and HOST_BYTE_ORDER must be defined to one of these. */ - -#if !defined (BIG_ENDIAN) -#define BIG_ENDIAN 4321 -#endif - -#if !defined (LITTLE_ENDIAN) -#define LITTLE_ENDIAN 1234 -#endif - -/* Target-system-dependent parameters for GDB. */ - -/* Target machine definition. This will be a symlink to one of the - tm-*.h files, built by the `configure' script. */ - -#include "tm.h" - -/* Number of bits in a char or unsigned char for the target machine. - Just like CHAR_BIT in but describes the target machine. */ -#if !defined (TARGET_CHAR_BIT) -#define TARGET_CHAR_BIT 8 -#endif - -/* Number of bits in a short or unsigned short for the target machine. */ -#if !defined (TARGET_SHORT_BIT) -#define TARGET_SHORT_BIT (2 * TARGET_CHAR_BIT) -#endif - -/* Number of bits in an int or unsigned int for the target machine. */ -#if !defined (TARGET_INT_BIT) -#define TARGET_INT_BIT (4 * TARGET_CHAR_BIT) -#endif - -/* Number of bits in a long or unsigned long for the target machine. */ -#if !defined (TARGET_LONG_BIT) -#define TARGET_LONG_BIT (4 * TARGET_CHAR_BIT) -#endif - -/* Number of bits in a long long or unsigned long long for the target machine. */ -#if !defined (TARGET_LONG_LONG_BIT) -#define TARGET_LONG_LONG_BIT (2 * TARGET_LONG_BIT) -#endif - -/* Number of bits in a float for the target machine. */ -#if !defined (TARGET_FLOAT_BIT) -#define TARGET_FLOAT_BIT (4 * TARGET_CHAR_BIT) -#endif - -/* Number of bits in a double for the target machine. */ -#if !defined (TARGET_DOUBLE_BIT) -#define TARGET_DOUBLE_BIT (8 * TARGET_CHAR_BIT) -#endif - -/* Number of bits in a long double for the target machine. */ -#if !defined (TARGET_LONG_DOUBLE_BIT) -#define TARGET_LONG_DOUBLE_BIT (2 * TARGET_DOUBLE_BIT) -#endif - -/* Number of bits in a "complex" for the target machine. */ -#if !defined (TARGET_COMPLEX_BIT) -#define TARGET_COMPLEX_BIT (2 * TARGET_FLOAT_BIT) -#endif - -/* Number of bits in a "double complex" for the target machine. */ -#if !defined (TARGET_DOUBLE_COMPLEX_BIT) -#define TARGET_DOUBLE_COMPLEX_BIT (2 * TARGET_DOUBLE_BIT) -#endif - -/* Number of bits in a pointer for the target machine */ -#if !defined (TARGET_PTR_BIT) -#define TARGET_PTR_BIT TARGET_INT_BIT -#endif - -/* If we picked up a copy of CHAR_BIT from a configuration file - (which may get it by including ) then use it to set - the number of bits in a host char. If not, use the same size - as the target. */ - -#if defined (CHAR_BIT) -#define HOST_CHAR_BIT CHAR_BIT -#else -#define HOST_CHAR_BIT TARGET_CHAR_BIT -#endif - -/* The bit byte-order has to do just with numbering of bits in - debugging symbols and such. Conceptually, it's quite separate - from byte/word byte order. */ - -#if !defined (BITS_BIG_ENDIAN) -#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. */ -#endif /* BITS_BIG_ENDIAN not defined. */ - -/* In findvar.c. */ -LONGEST extract_signed_integer PARAMS ((void *, int)); -unsigned LONGEST extract_unsigned_integer PARAMS ((void *, int)); -CORE_ADDR extract_address PARAMS ((void *, int)); - -void store_signed_integer PARAMS ((void *, int, LONGEST)); -void store_unsigned_integer PARAMS ((void *, int, unsigned LONGEST)); -void store_address PARAMS ((void *, int, CORE_ADDR)); - -double extract_floating PARAMS ((void *, int)); -void store_floating PARAMS ((void *, int, double)); - -/* On some machines there are bits in addresses which are not really - part of the address, but are used by the kernel, the hardware, etc. - for special purposes. ADDR_BITS_REMOVE takes out any such bits - so we get a "real" address such as one would find in a symbol - table. This is used only for addresses of instructions, and even then - I'm not sure it's used in all contexts. It exists to deal with there - being a few stray bits in the PC which would mislead us, not as some sort - of generic thing to handle alignment or segmentation (it's possible it - should be in TARGET_READ_PC instead). */ -#if !defined (ADDR_BITS_REMOVE) -#define ADDR_BITS_REMOVE(addr) (addr) -#endif /* No ADDR_BITS_REMOVE. */ - -/* From valops.c */ - -extern CORE_ADDR -push_bytes PARAMS ((CORE_ADDR, char *, int)); - -extern CORE_ADDR -push_word PARAMS ((CORE_ADDR, unsigned LONGEST)); - -/* 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 - for a specific environment. For example, the maintenance commands - are there for the benefit of gdb maintainers. As another example, - some environments really don't need gdb's that are able to read N - different object file formats. In order to make it possible (but - not necessarily recommended) to build "stripped down" versions of - gdb, the following defines control selective compilation of those - parts of gdb which can be safely left out when necessary. Note that - the default is to include everything. */ - -#ifndef MAINTENANCE_CMDS -#define MAINTENANCE_CMDS 1 -#endif - -#endif /* !defined (DEFS_H) */ diff --git a/gnu/usr.bin/gdb/gdb/demangle.c b/gnu/usr.bin/gdb/gdb/demangle.c deleted file mode 100644 index e4cc996..0000000 --- a/gnu/usr.bin/gdb/gdb/demangle.c +++ /dev/null @@ -1,181 +0,0 @@ -/* Basic C++ demangling support for GDB. - Copyright 1991, 1992 Free Software Foundation, Inc. - Written by Fred Fish at 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* This file contains support code for C++ demangling that is common - to a styles of demangling, and GDB specific. */ - -#include "defs.h" -#include "command.h" -#include "gdbcmd.h" -#include "demangle.h" -#include - -/* 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 - 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 -#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. */ - -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 [] = -{ - {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} -}; - -/* 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. - - 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 - 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. - - Note: Assumes that current_demangling_style_string always points to - a malloc'd string, even if it is a null-string. */ - -static void -set_demangling_command (ignore, from_tty, c) - char *ignore; - int from_tty; - struct cmd_list_element *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. */ - - for (dem = demanglers; dem -> demangling_style_name != NULL; dem++) - { - if (STREQ (current_demangling_style_string, - dem -> demangling_style_name)) - { - current_demangling_style = dem -> demangling_style; - break; - } - } - - /* Check to see if we found a match. If not, gripe about any non-empty - 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 (*current_demangling_style_string != '\0') - { - printf_unfiltered ("Unknown demangling style `%s'.\n", - current_demangling_style_string); - } - printf_unfiltered ("The currently understood settings are:\n\n"); - 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) - { - free (current_demangling_style_string); - current_demangling_style_string = - savestring (dem -> demangling_style_name, - strlen (dem -> demangling_style_name)); - } - } - if (current_demangling_style == unknown_demangling) - { - /* This can happen during initialization if gdb is compiled with - a DEMANGLING_STYLE value that is unknown, so pick the first - one as the default. */ - current_demangling_style = demanglers[0].demangling_style; - current_demangling_style_string = - savestring (demanglers[0].demangling_style_name, - strlen (demanglers[0].demangling_style_name)); - warning ("`%s' style demangling chosen as the default.\n", - current_demangling_style_string); - } - } -} - -/* Fake a "set demangling" command. */ - -void -set_demangling_style (style) - char *style; -{ - if (current_demangling_style_string != NULL) - { - free (current_demangling_style_string); - } - current_demangling_style_string = savestring (style, strlen (style)); - set_demangling_command ((char *) NULL, 0); -} - -void -_initialize_demangler () -{ - struct cmd_list_element *set, *show; - - set = add_set_cmd ("demangle-style", class_support, var_string_noescape, - (char *) ¤t_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; - - /* 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/gnu/usr.bin/gdb/gdb/demangle.h b/gnu/usr.bin/gdb/gdb/demangle.h deleted file mode 100644 index 7fee623..0000000 --- a/gnu/usr.bin/gdb/gdb/demangle.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Defs for interface to demanglers. - Copyright 1992 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. */ - - -#if !defined (DEMANGLE_H) -#define DEMANGLE_H - -#include - -/* Options passed to cplus_demangle (in 2nd parameter). */ - -#define DMGL_NO_OPTS 0 /* For readability... */ -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ - -#define DMGL_AUTO (1 << 8) -#define DMGL_GNU (1 << 9) -#define DMGL_LUCID (1 << 10) -#define DMGL_ARM (1 << 11) -/* If none of these are set, use 'current_demangling_style' as the default. */ -#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM) - -/* Enumeration of possible demangling styles. - - Lucid and ARM styles are still kept logically distinct, even though - they now both behave identically. The resulting style is actual the - union of both. I.E. either style recognizes both "__pt__" and "__rf__" - for operator "->", even though the first is lucid style and the second - is ARM style. (FIXME?) */ - -extern enum demangling_styles -{ - unknown_demangling = 0, - auto_demangling = DMGL_AUTO, - gnu_demangling = DMGL_GNU, - lucid_demangling = DMGL_LUCID, - arm_demangling = DMGL_ARM -} current_demangling_style; - -/* Define string names for the various demangling styles. */ - -#define AUTO_DEMANGLING_STYLE_STRING "auto" -#define GNU_DEMANGLING_STYLE_STRING "gnu" -#define LUCID_DEMANGLING_STYLE_STRING "lucid" -#define ARM_DEMANGLING_STYLE_STRING "arm" - -/* Some macros to test what demangling style is active. */ - -#define CURRENT_DEMANGLING_STYLE current_demangling_style -#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO) -#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU) -#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID) -#define ARM_DEMANGLING (CURRENT_DEMANGLING_STYLE & DMGL_ARM) - -extern char * -cplus_demangle PARAMS ((CONST char *mangled, int options)); - -extern int -cplus_demangle_opname PARAMS ((char *opname, char *result, int options)); - -/* Note: This sets global state. FIXME if you care about multi-threading. */ - -extern void -set_cplus_marker_for_demangling PARAMS ((int ch)); - -#endif /* DEMANGLE_H */ diff --git a/gnu/usr.bin/gdb/gdb/dis-asm.h b/gnu/usr.bin/gdb/gdb/dis-asm.h deleted file mode 100644 index fde2059..0000000 --- a/gnu/usr.bin/gdb/gdb/dis-asm.h +++ /dev/null @@ -1,179 +0,0 @@ -/* Interface between the opcode library and its callers. - Written by Cygnus Support, 1993. - - The opcode library (libopcodes.a) provides instruction decoders for - a large variety of instruction sets, callable with an identical - interface, for making instruction-processing programs more independent - of the instruction set being processed. */ - -#include -#include "bfd.h" - -typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...)); - -enum dis_insn_type { - dis_noninsn, /* Not a valid instruction */ - dis_nonbranch, /* Not a branch instruction */ - dis_branch, /* Unconditional branch */ - dis_condbranch, /* Conditional branch */ - dis_jsr, /* Jump to subroutine */ - dis_condjsr, /* Conditional jump to subroutine */ - dis_dref, /* Data reference instruction */ - dis_dref2 /* Two data references in instruction */ -}; - -/* This struct is passed into the instruction decoding routine, - and is passed back out into each callback. The various fields are used - for conveying information from your main routine into your callbacks, - for passing information into the instruction decoders (such as the - addresses of the callback functions), or for passing information - back from the instruction decoders to their callers. - - It must be initialized before it is first passed; this can be done - by hand, or using one of the initialization macros below. */ - -typedef struct disassemble_info { - fprintf_ftype fprintf_func; - FILE *stream; - PTR application_data; - - /* For use by the disassembler. */ - int flags; - PTR private_data; - - /* Function used to get bytes to disassemble. MEMADDR is the - address of the stuff to be disassembled, MYADDR is the address to - put the bytes in, and LENGTH is the number of bytes to read. - INFO is a pointer to this struct. - Returns an errno value or 0 for success. */ - int (*read_memory_func) - PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length, - struct disassemble_info *info)); - - /* Function which should be called if we get an error that we can't - recover from. STATUS is the errno value from read_memory_func and - MEMADDR is the address that we were trying to read. INFO is a - pointer to this struct. */ - void (*memory_error_func) - PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info)); - - /* Function called to print ADDR. */ - void (*print_address_func) - PARAMS ((bfd_vma addr, struct disassemble_info *info)); - - /* These are for buffer_read_memory. */ - bfd_byte *buffer; - bfd_vma buffer_vma; - int buffer_length; - - /* Results from instruction decoders. Not all decoders yet support - this information. This info is set each time an instruction is - decoded, and is only valid for the last such instruction. - - To determine whether this decoder supports this information, set - insn_info_valid to 0, decode an instruction, then check it. */ - - char insn_info_valid; /* Branch info has been set. */ - char branch_delay_insns; /* How many sequential insn's will run before - a branch takes effect. (0 = normal) */ - char data_size; /* Size of data reference in insn, in bytes */ - enum dis_insn_type insn_type; /* Type of instruction */ - bfd_vma target; /* Target address of branch or dref, if known; - zero if unknown. */ - bfd_vma target2; /* Second target address for dref2 */ - -} disassemble_info; - - - - - - -/* Standard disassemblers. Disassemble one instruction at the given - target address. Return number of bytes processed. */ -typedef int (*disassembler_ftype) - PARAMS((bfd_vma, disassemble_info *)); - -extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*)); -extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*)); - -/* Fetch the disassembler for a given BFD, if that support is available. */ -extern disassembler_ftype disassembler PARAMS ((bfd *)); - - -/* This block of definitions is for particular callers who read instructions - into a buffer before calling the instruction decoder. */ - -/* Here is a function which callers may wish to use for read_memory_func. - It gets bytes from a buffer. */ -extern int buffer_read_memory - PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *)); - -/* This function goes with buffer_read_memory. - It prints a message using info->fprintf_func and info->stream. */ -extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *)); - - -/* Just print the address is hex. This is included for completeness even - though both GDB and objdump provide their own (to print symbolic - addresses). */ -extern void generic_print_address - PARAMS ((bfd_vma, struct disassemble_info *)); - -#define INIT_DISASSEMBLE_INFO(INFO, STREAM) \ - (INFO).fprintf_func = (fprintf_ftype)fprintf, \ - (INFO).stream = (STREAM), \ - (INFO).buffer = NULL, \ - (INFO).buffer_vma = 0, \ - (INFO).buffer_length = 0, \ - (INFO).read_memory_func = buffer_read_memory, \ - (INFO).memory_error_func = perror_memory, \ - (INFO).print_address_func = generic_print_address, \ - (INFO).insn_info_valid = 0 - - - - -/* This block of definitions is for calling the instruction decoders - from GDB. */ - -/* GDB--Like target_read_memory, but slightly different parameters. */ -extern int -dis_asm_read_memory PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int len, - disassemble_info *info)); - -/* GDB--Like memory_error with slightly different parameters. */ -extern void -dis_asm_memory_error - PARAMS ((int status, bfd_vma memaddr, disassemble_info *info)); - -/* GDB--Like print_address with slightly different parameters. */ -extern void -dis_asm_print_address PARAMS ((bfd_vma addr, disassemble_info *info)); - -#define GDB_INIT_DISASSEMBLE_INFO(INFO, STREAM) \ - (INFO).fprintf_func = (fprintf_ftype)fprintf_filtered, \ - (INFO).stream = (STREAM), \ - (INFO).read_memory_func = dis_asm_read_memory, \ - (INFO).memory_error_func = dis_asm_memory_error, \ - (INFO).print_address_func = dis_asm_print_address, \ - (INFO).insn_info_valid = 0 diff --git a/gnu/usr.bin/gdb/gdb/dis-buf.c b/gnu/usr.bin/gdb/gdb/dis-buf.c deleted file mode 100644 index d184b28..0000000 --- a/gnu/usr.bin/gdb/gdb/dis-buf.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Disassemble from a buffer, for GNU. - Copyright (C) 1993, 1994 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "dis-asm.h" -#include "sysdep.h" -#include - -/* Get LENGTH bytes from info's buffer, at target address memaddr. - Transfer them to myaddr. */ -int -buffer_read_memory (memaddr, myaddr, length, info) - bfd_vma memaddr; - bfd_byte *myaddr; - int length; - struct disassemble_info *info; -{ - if (memaddr < info->buffer_vma - || memaddr + length > info->buffer_vma + info->buffer_length) - /* Out of bounds. Use EIO because GDB uses it. */ - return EIO; - memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length); - return 0; -} - -/* Print an error message. We can assume that this is in response to - an error return from buffer_read_memory. */ -void -perror_memory (status, memaddr, info) - int status; - bfd_vma memaddr; - struct disassemble_info *info; -{ - if (status != EIO) - /* Can't happen. */ - (*info->fprintf_func) (info->stream, "Unknown error %d\n", status); - else - /* Actually, address between memaddr and memaddr + len was - out of bounds. */ - (*info->fprintf_func) (info->stream, - "Address 0x%x is out of bounds.\n", memaddr); -} - -/* This could be in a separate file, to save miniscule amounts of space - in statically linked executables. */ - -/* Just print the address is hex. This is included for completeness even - though both GDB and objdump provide their own (to print symbolic - addresses). */ - -void -generic_print_address (addr, info) - bfd_vma addr; - struct disassemble_info *info; -{ - (*info->fprintf_func) (info->stream, "0x%x", addr); -} diff --git a/gnu/usr.bin/gdb/gdb/disassemble.c b/gnu/usr.bin/gdb/gdb/disassemble.c deleted file mode 100644 index fe66107..0000000 --- a/gnu/usr.bin/gdb/gdb/disassemble.c +++ /dev/null @@ -1,148 +0,0 @@ -/* Select disassembly routine for specified architecture. - Copyright 1994 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "ansidecl.h" -#include "dis-asm.h" - -#ifdef ARCH_all -#define ARCH_a29k -#define ARCH_alpha -#define ARCH_h8300 -#define ARCH_h8500 -#define ARCH_hppa -#define ARCH_i386 -#define ARCH_i960 -#define ARCH_m68k -#define ARCH_m88k -#define ARCH_mips -#define ARCH_ns32k -#define ARCH_powerpc -#define ARCH_rs6000 -#define ARCH_sh -#define ARCH_sparc -#define ARCH_z8k -#endif - -disassembler_ftype -disassembler (abfd) - bfd *abfd; -{ - enum bfd_architecture a = bfd_get_arch (abfd); - disassembler_ftype disassemble; - - switch (a) - { - /* If you add a case to this table, also add it to the - ARCH_all definition right above this function. */ -#ifdef ARCH_a29k - case bfd_arch_a29k: - /* As far as I know we only handle big-endian 29k objects. */ - disassemble = print_insn_big_a29k; - break; -#endif -#ifdef ARCH_alpha - case bfd_arch_alpha: - disassemble = print_insn_alpha; - break; -#endif -#ifdef ARCH_h8300 - case bfd_arch_h8300: - if (bfd_get_mach(abfd) == bfd_mach_h8300h) - disassemble = print_insn_h8300h; - else - disassemble = print_insn_h8300; - break; -#endif -#ifdef ARCH_h8500 - case bfd_arch_h8500: - disassemble = print_insn_h8500; - break; -#endif -#ifdef ARCH_hppa - case bfd_arch_hppa: - disassemble = print_insn_hppa; - break; -#endif -#ifdef ARCH_i386 - case bfd_arch_i386: - disassemble = print_insn_i386; - break; -#endif -#ifdef ARCH_i960 - case bfd_arch_i960: - disassemble = print_insn_i960; - break; -#endif -#ifdef ARCH_m68k - case bfd_arch_m68k: - disassemble = print_insn_m68k; - break; -#endif -#ifdef ARCH_m88k - case bfd_arch_m88k: - disassemble = print_insn_m88k; - break; -#endif -#ifdef ARCH_ns32k - case bfd_arch_ns32k: - disassemble = print_insn_ns32k; - break; -#endif -#ifdef ARCH_mips - case bfd_arch_mips: - if (abfd->xvec->byteorder_big_p) - disassemble = print_insn_big_mips; - else - disassemble = print_insn_little_mips; - break; -#endif -#ifdef ARCH_powerpc - case bfd_arch_powerpc: - if (abfd->xvec->byteorder_big_p) - disassemble = print_insn_big_powerpc; - else - disassemble = print_insn_little_powerpc; - break; -#endif -#ifdef ARCH_rs6000 - case bfd_arch_rs6000: - disassemble = print_insn_rs6000; - break; -#endif -#ifdef ARCH_sh - case bfd_arch_sh: - disassemble = print_insn_sh; - break; -#endif -#ifdef ARCH_sparc - case bfd_arch_sparc: - disassemble = print_insn_sparc; - break; -#endif -#ifdef ARCH_z8k - case bfd_arch_z8k: - if (bfd_get_mach(abfd) == bfd_mach_z8001) - disassemble = print_insn_z8001; - else - disassemble = print_insn_z8002; - break; -#endif - default: - return 0; - } - return disassemble; -} diff --git a/gnu/usr.bin/gdb/gdb/dwarfread.c b/gnu/usr.bin/gdb/gdb/dwarfread.c deleted file mode 100644 index a373e4e..0000000 --- a/gnu/usr.bin/gdb/gdb/dwarfread.c +++ /dev/null @@ -1,3876 +0,0 @@ -/* DWARF debugging format support for GDB. - Copyright (C) 1991, 1992, 1993, 1994 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. - -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. */ - -/* - -FIXME: Do we need to generate dependencies in partial symtabs? -(Perhaps we don't need to). - -FIXME: Resolve minor differences between what information we put in the -partial symbol table and what dbxread puts in. For example, we don't yet -put enum constants there. And dbxread seems to invent a lot of typedefs -we never see. Use the new printpsym command to see the partial symbol table -contents. - -FIXME: Figure out a better way to tell gdb about the name of the function -contain the user's entry point (I.E. main()) - -FIXME: See other FIXME's and "ifdef 0" scattered throughout the code for -other things to work on, if you get bored. :-) - -*/ - -#include "defs.h" -#include "bfd.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "symfile.h" -#include "objfiles.h" -#include "elf/dwarf.h" -#include "buildsym.h" -#include "demangle.h" -#include "expression.h" /* Needed for enum exp_opcode in language.h, sigh... */ -#include "language.h" -#include "complaints.h" - -#include -#include - -#ifndef NO_SYS_FILE -#include -#endif - -/* FIXME -- convert this to SEEK_SET a la POSIX, move to config files. */ -#ifndef L_SET -#define L_SET 0 -#endif - -/* Some macros to provide DIE info for complaints. */ - -#define DIE_ID (curdie!=NULL ? curdie->die_ref : 0) -#define DIE_NAME (curdie!=NULL && curdie->at_name!=NULL) ? curdie->at_name : "" - -/* Complaints that can be issued during DWARF debug info reading. */ - -struct complaint no_bfd_get_N = -{ - "DIE @ 0x%x \"%s\", no bfd support for %d byte data object", 0, 0 -}; - -struct complaint malformed_die = -{ - "DIE @ 0x%x \"%s\", malformed DIE, bad length (%d bytes)", 0, 0 -}; - -struct complaint bad_die_ref = -{ - "DIE @ 0x%x \"%s\", reference to DIE (0x%x) outside compilation unit", 0, 0 -}; - -struct complaint unknown_attribute_form = -{ - "DIE @ 0x%x \"%s\", unknown attribute form (0x%x)", 0, 0 -}; - -struct complaint unknown_attribute_length = -{ - "DIE @ 0x%x \"%s\", unknown attribute length, skipped remaining attributes", 0, 0 -}; - -struct complaint unexpected_fund_type = -{ - "DIE @ 0x%x \"%s\", unexpected fundamental type 0x%x", 0, 0 -}; - -struct complaint unknown_type_modifier = -{ - "DIE @ 0x%x \"%s\", unknown type modifier %u", 0, 0 -}; - -struct complaint volatile_ignored = -{ - "DIE @ 0x%x \"%s\", type modifier 'volatile' ignored", 0, 0 -}; - -struct complaint const_ignored = -{ - "DIE @ 0x%x \"%s\", type modifier 'const' ignored", 0, 0 -}; - -struct complaint botched_modified_type = -{ - "DIE @ 0x%x \"%s\", botched modified type decoding (mtype 0x%x)", 0, 0 -}; - -struct complaint op_deref2 = -{ - "DIE @ 0x%x \"%s\", OP_DEREF2 address 0x%x not handled", 0, 0 -}; - -struct complaint op_deref4 = -{ - "DIE @ 0x%x \"%s\", OP_DEREF4 address 0x%x not handled", 0, 0 -}; - -struct complaint basereg_not_handled = -{ - "DIE @ 0x%x \"%s\", BASEREG %d not handled", 0, 0 -}; - -struct complaint dup_user_type_allocation = -{ - "DIE @ 0x%x \"%s\", internal error: duplicate user type allocation", 0, 0 -}; - -struct complaint dup_user_type_definition = -{ - "DIE @ 0x%x \"%s\", internal error: duplicate user type definition", 0, 0 -}; - -struct complaint missing_tag = -{ - "DIE @ 0x%x \"%s\", missing class, structure, or union tag", 0, 0 -}; - -struct complaint bad_array_element_type = -{ - "DIE @ 0x%x \"%s\", bad array element type attribute 0x%x", 0, 0 -}; - -struct complaint subscript_data_items = -{ - "DIE @ 0x%x \"%s\", can't decode subscript data items", 0, 0 -}; - -struct complaint unhandled_array_subscript_format = -{ - "DIE @ 0x%x \"%s\", array subscript format 0x%x not handled yet", 0, 0 -}; - -struct complaint unknown_array_subscript_format = -{ - "DIE @ 0x%x \"%s\", unknown array subscript format %x", 0, 0 -}; - -struct complaint not_row_major = -{ - "DIE @ 0x%x \"%s\", array not row major; not handled correctly", 0, 0 -}; - -typedef unsigned int DIE_REF; /* Reference to a DIE */ - -#ifndef GCC_PRODUCER -#define GCC_PRODUCER "GNU C " -#endif - -#ifndef GPLUS_PRODUCER -#define GPLUS_PRODUCER "GNU C++ " -#endif - -#ifndef LCC_PRODUCER -#define LCC_PRODUCER "NCR C/C++" -#endif - -#ifndef CHILL_PRODUCER -#define CHILL_PRODUCER "GNU Chill " -#endif - -/* Flags to target_to_host() that tell whether or not the data object is - expected to be signed. Used, for example, when fetching a signed - integer in the target environment which is used as a signed integer - in the host environment, and the two environments have different sized - ints. In this case, *somebody* has to sign extend the smaller sized - int. */ - -#define GET_UNSIGNED 0 /* No sign extension required */ -#define GET_SIGNED 1 /* Sign extension required */ - -/* Defines for things which are specified in the document "DWARF Debugging - Information Format" published by UNIX International, Programming Languages - SIG. These defines are based on revision 1.0.0, Jan 20, 1992. */ - -#define SIZEOF_DIE_LENGTH 4 -#define SIZEOF_DIE_TAG 2 -#define SIZEOF_ATTRIBUTE 2 -#define SIZEOF_FORMAT_SPECIFIER 1 -#define SIZEOF_FMT_FT 2 -#define SIZEOF_LINETBL_LENGTH 4 -#define SIZEOF_LINETBL_LINENO 4 -#define SIZEOF_LINETBL_STMT 2 -#define SIZEOF_LINETBL_DELTA 4 -#define SIZEOF_LOC_ATOM_CODE 1 - -#define FORM_FROM_ATTR(attr) ((attr) & 0xF) /* Implicitly specified */ - -/* Macros that return the sizes of various types of data in the target - environment. - - FIXME: Currently these are just compile time constants (as they are in - other parts of gdb as well). They need to be able to get the right size - either from the bfd or possibly from the DWARF info. It would be nice if - the DWARF producer inserted DIES that describe the fundamental types in - the target environment into the DWARF info, similar to the way dbx stabs - producers produce information about their fundamental types. */ - -#define TARGET_FT_POINTER_SIZE(objfile) (TARGET_PTR_BIT / TARGET_CHAR_BIT) -#define TARGET_FT_LONG_SIZE(objfile) (TARGET_LONG_BIT / TARGET_CHAR_BIT) - -/* The Amiga SVR4 header file defines AT_element_list as a - FORM_BLOCK2, and this is the value emitted by the AT&T compiler. - However, the Issue 2 DWARF specification from AT&T defines it as - a FORM_BLOCK4, as does the latest specification from UI/PLSIG. - For backwards compatibility with the AT&T compiler produced executables - we define AT_short_element_list for this variant. */ - -#define AT_short_element_list (0x00f0|FORM_BLOCK2) - -/* External variables referenced. */ - -extern int info_verbose; /* From main.c; nonzero => verbose */ -extern char *warning_pre_print; /* From utils.c */ - -/* The DWARF debugging information consists of two major pieces, - one is a block of DWARF Information Entries (DIE's) and the other - is a line number table. The "struct dieinfo" structure contains - the information for a single DIE, the one currently being processed. - - In order to make it easier to randomly access the attribute fields - of the current DIE, which are specifically unordered within the DIE, - each DIE is scanned and an instance of the "struct dieinfo" - structure is initialized. - - Initialization is done in two levels. The first, done by basicdieinfo(), - just initializes those fields that are vital to deciding whether or not - to use this DIE, how to skip past it, etc. The second, done by the - function completedieinfo(), fills in the rest of the information. - - Attributes which have block forms are not interpreted at the time - the DIE is scanned, instead we just save pointers to the start - of their value fields. - - Some fields have a flag _p that is set when the value of the - field is valid (I.E. we found a matching attribute in the DIE). Since - we may want to test for the presence of some attributes in the DIE, - such as AT_low_pc, without restricting the values of the field, - we need someway to note that we found such an attribute. - - */ - -typedef char BLOCK; - -struct dieinfo { - char * die; /* Pointer to the raw DIE data */ - unsigned long die_length; /* Length of the raw DIE data */ - DIE_REF die_ref; /* Offset of this DIE */ - unsigned short die_tag; /* Tag for this DIE */ - unsigned long at_padding; - unsigned long at_sibling; - BLOCK * at_location; - char * at_name; - unsigned short at_fund_type; - BLOCK * at_mod_fund_type; - unsigned long at_user_def_type; - BLOCK * at_mod_u_d_type; - unsigned short at_ordering; - BLOCK * at_subscr_data; - unsigned long at_byte_size; - unsigned short at_bit_offset; - unsigned long at_bit_size; - BLOCK * at_element_list; - unsigned long at_stmt_list; - unsigned long at_low_pc; - unsigned long at_high_pc; - unsigned long at_language; - unsigned long at_member; - unsigned long at_discr; - BLOCK * at_discr_value; - BLOCK * at_string_length; - char * at_comp_dir; - char * at_producer; - unsigned long at_start_scope; - unsigned long at_stride_size; - unsigned long at_src_info; - char * at_prototyped; - unsigned int has_at_low_pc:1; - unsigned int has_at_stmt_list:1; - unsigned int has_at_byte_size:1; - unsigned int short_element_list:1; -}; - -static int diecount; /* Approximate count of dies for compilation unit */ -static struct dieinfo *curdie; /* For warnings and such */ - -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 */ -/* 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, - pass the appropriate section number to end_symtab). */ -static CORE_ADDR baseaddr; /* Add to each symbol value */ - -/* The section offsets used in the current psymtab or symtab. FIXME, - only used to pass one value (baseaddr) at the moment. */ -static struct section_offsets *base_section_offsets; - -/* Each partial symbol table entry contains a pointer to private data for the - read_symtab() function to use when expanding a partial symbol table entry - to a full symbol table entry. For DWARF debugging info, this data is - contained in the following structure and macros are provided for easy - access to the members given a pointer to a partial symbol table entry. - - dbfoff Always the absolute file offset to the start of the ".debug" - section for the file containing the DIE's being accessed. - - dbroff Relative offset from the start of the ".debug" access to the - first DIE to be accessed. When building the partial symbol - table, this value will be zero since we are accessing the - entire ".debug" section. When expanding a partial symbol - table entry, this value will be the offset to the first - DIE for the compilation unit containing the symbol that - triggers the expansion. - - dblength The size of the chunk of DIE's being examined, in bytes. - - lnfoff The absolute file offset to the line table fragment. Ignored - when building partial symbol tables, but used when expanding - them, and contains the absolute file offset to the fragment - of the ".line" section containing the line numbers for the - current compilation unit. - */ - -struct dwfinfo { - file_ptr dbfoff; /* Absolute file offset to start of .debug section */ - int dbroff; /* Relative offset from start of .debug section */ - int dblength; /* Size of the chunk of DIE's being examined */ - file_ptr lnfoff; /* Absolute file offset to line table fragment */ -}; - -#define DBFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbfoff) -#define DBROFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbroff) -#define DBLENGTH(p) (((struct dwfinfo *)((p)->read_symtab_private))->dblength) -#define LNFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->lnfoff) - -/* 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 */ - -struct pending **list_in_scope = &file_symbols; - -/* DIES which have user defined types or modified user defined types refer to - other DIES for the type information. Thus we need to associate the offset - of a DIE for a user defined type with a pointer to the type information. - - Originally this was done using a simple but expensive algorithm, with an - array of unsorted structures, each containing an offset/type-pointer pair. - This array was scanned linearly each time a lookup was done. The result - was that gdb was spending over half it's startup time munging through this - array of pointers looking for a structure that had the right offset member. - - The second attempt used the same array of structures, but the array was - sorted using qsort each time a new offset/type was recorded, and a binary - search was used to find the type pointer for a given DIE offset. This was - even slower, due to the overhead of sorting the array each time a new - offset/type pair was entered. - - The third attempt uses a fixed size array of type pointers, indexed by a - value derived from the DIE offset. Since the minimum DIE size is 4 bytes, - we can divide any DIE offset by 4 to obtain a unique index into this fixed - size array. Since each element is a 4 byte pointer, it takes exactly as - much memory to hold this array as to hold the DWARF info for a given - compilation unit. But it gets freed as soon as we are done with it. - This has worked well in practice, as a reasonable tradeoff between memory - consumption and speed, without having to resort to much more complicated - algorithms. */ - -static struct type **utypes; /* Pointer to array of user type pointers */ -static int numutypes; /* Max number of user type pointers */ - -/* 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_ 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 */ - -/* Record the language for the compilation unit which is currently being - processed. We know it once we have seen the TAG_compile_unit DIE, - and we need it while processing the DIE's for that compilation unit. - It is eventually saved in the symtab structure, but we don't finalize - the symtab struct until we have processed all the DIE's for the - compilation unit. We also need to get and save a pointer to the - language struct for this language, so we can call the language - dependent routines for doing things such as creating fundamental - types. */ - -static enum language cu_language; -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 int -attribute_size PARAMS ((unsigned int)); - -static unsigned long -target_to_host PARAMS ((char *, int, int, struct objfile *)); - -static void -add_enum_psymbol PARAMS ((struct dieinfo *, struct objfile *)); - -static void -handle_producer PARAMS ((char *)); - -static void -read_file_scope PARAMS ((struct dieinfo *, char *, char *, struct objfile *)); - -static void -read_func_scope PARAMS ((struct dieinfo *, char *, char *, struct objfile *)); - -static void -read_lexical_block_scope PARAMS ((struct dieinfo *, char *, char *, - struct objfile *)); - -static void -scan_partial_symbols PARAMS ((char *, char *, struct objfile *)); - -static void -scan_compilation_units PARAMS ((char *, char *, file_ptr, - file_ptr, struct objfile *)); - -static void -add_partial_symbol PARAMS ((struct dieinfo *, struct objfile *)); - -static void -init_psymbol_list PARAMS ((struct objfile *, int)); - -static void -basicdieinfo PARAMS ((struct dieinfo *, char *, struct objfile *)); - -static void -completedieinfo PARAMS ((struct dieinfo *, struct objfile *)); - -static void -dwarf_psymtab_to_symtab PARAMS ((struct partial_symtab *)); - -static void -psymtab_to_symtab_1 PARAMS ((struct partial_symtab *)); - -static void -read_ofile_symtab PARAMS ((struct partial_symtab *)); - -static void -process_dies PARAMS ((char *, char *, struct objfile *)); - -static void -read_structure_scope PARAMS ((struct dieinfo *, char *, char *, - struct objfile *)); - -static struct type * -decode_array_element_type PARAMS ((char *)); - -static struct type * -decode_subscript_data_item PARAMS ((char *, char *)); - -static void -dwarf_read_array_type PARAMS ((struct dieinfo *)); - -static void -read_tag_pointer_type PARAMS ((struct dieinfo *dip)); - -static void -read_tag_string_type PARAMS ((struct dieinfo *dip)); - -static void -read_subroutine_type PARAMS ((struct dieinfo *, char *, char *)); - -static void -read_enumeration PARAMS ((struct dieinfo *, char *, char *, struct objfile *)); - -static struct type * -struct_type PARAMS ((struct dieinfo *, char *, char *, struct objfile *)); - -static struct type * -enum_type PARAMS ((struct dieinfo *, struct objfile *)); - -static void -decode_line_numbers PARAMS ((char *)); - -static struct type * -decode_die_type PARAMS ((struct dieinfo *)); - -static struct type * -decode_mod_fund_type PARAMS ((char *)); - -static struct type * -decode_mod_u_d_type PARAMS ((char *)); - -static struct type * -decode_modified_type PARAMS ((char *, unsigned int, int)); - -static struct type * -decode_fund_type PARAMS ((unsigned int)); - -static char * -create_name PARAMS ((char *, struct obstack *)); - -static struct type * -lookup_utype PARAMS ((DIE_REF)); - -static struct type * -alloc_utype PARAMS ((DIE_REF, struct type *)); - -static struct symbol * -new_symbol PARAMS ((struct dieinfo *, struct objfile *)); - -static void -synthesize_typedef PARAMS ((struct dieinfo *, struct objfile *, - struct type *)); - -static int -locval PARAMS ((char *)); - -static void -set_cu_language PARAMS ((struct dieinfo *)); - -static struct type * -dwarf_fundamental_type PARAMS ((struct objfile *, int)); - - -/* - -LOCAL FUNCTION - - dwarf_fundamental_type -- lookup or create a fundamental type - -SYNOPSIS - - struct type * - dwarf_fundamental_type (struct objfile *objfile, int typeid) - -DESCRIPTION - - DWARF version 1 doesn't supply any fundamental type information, - so gdb has to construct such types. It has a fixed number of - fundamental types that it knows how to construct, which is the - union of all types that it knows how to construct for all languages - that it knows about. These are enumerated in gdbtypes.h. - - As an example, assume we find a DIE that references a DWARF - fundamental type of FT_integer. We first look in the ftypes - array to see if we already have such a type, indexed by the - gdb internal value of FT_INTEGER. If so, we simply return a - pointer to that type. If not, then we ask an appropriate - language dependent routine to create a type FT_INTEGER, using - defaults reasonable for the current target machine, and install - that type in ftypes for future reference. - -RETURNS - - Pointer to a fundamental type. - -*/ - -static struct type * -dwarf_fundamental_type (objfile, typeid) - struct objfile *objfile; - int typeid; -{ - if (typeid < 0 || typeid >= FT_NUM_MEMBERS) - { - 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]); -} - -/* - -LOCAL FUNCTION - - set_cu_language -- set local copy of language for compilation unit - -SYNOPSIS - - void - set_cu_language (struct dieinfo *dip) - -DESCRIPTION - - Decode the language attribute for a compilation unit DIE and - remember what the language was. We use this at various times - when processing DIE's for a given compilation unit. - -RETURNS - - No return value. - - */ - -static void -set_cu_language (dip) - struct dieinfo *dip; -{ - switch (dip -> at_language) - { - case LANG_C89: - case LANG_C: - cu_language = language_c; - break; - case LANG_C_PLUS_PLUS: - cu_language = language_cplus; - break; - case LANG_CHILL: - cu_language = language_chill; - break; - case LANG_MODULA2: - cu_language = language_m2; - 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; - break; - default: - /* If no at_language, try to deduce one from the filename */ - cu_language = deduce_language_from_filename (dip -> at_name); - break; - } - cu_language_defn = language_def (cu_language); -} - -/* - -GLOBAL FUNCTION - - dwarf_build_psymtabs -- build partial symtabs from DWARF debug info - -SYNOPSIS - - void dwarf_build_psymtabs (struct objfile *objfile, - struct section_offsets *section_offsets, - int mainline, file_ptr dbfoff, unsigned int dbfsize, - file_ptr lnoffset, unsigned int lnsize) - -DESCRIPTION - - This function is called upon to build partial symtabs from files - containing DIE's (Dwarf Information Entries) and DWARF line numbers. - - It is passed a bfd* containing the DIES - and line number information, the corresponding filename for that - file, a base address for relocating the symbols, a flag indicating - whether or not this debugging information is from a "main symbol - table" rather than a shared library or dynamically linked file, - and file offset/size pairs for the DIE information and line number - information. - -RETURNS - - No return value. - - */ - -void -dwarf_build_psymtabs (objfile, section_offsets, mainline, dbfoff, dbfsize, - lnoffset, lnsize) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; - file_ptr dbfoff; - unsigned int dbfsize; - file_ptr lnoffset; - unsigned int lnsize; -{ - bfd *abfd = objfile->obfd; - struct cleanup *back_to; - - current_objfile = objfile; - dbsize = dbfsize; - dbbase = xmalloc (dbsize); - dbroff = 0; - if ((bfd_seek (abfd, dbfoff, L_SET) != 0) || - (bfd_read (dbbase, dbsize, 1, abfd) != dbsize)) - { - free (dbbase); - error ("can't read DWARF data from '%s'", bfd_get_filename (abfd)); - } - back_to = make_cleanup (free, dbbase); - - /* If we are reinitializing, or if we have never loaded syms yet, init. - Since we have no idea how many DIES we are looking at, we just guess - some arbitrary value. */ - - if (mainline || objfile -> global_psymbols.size == 0 || - objfile -> static_psymbols.size == 0) - { - init_psymbol_list (objfile, 1024); - } - - /* Save the relocation factor where everybody can see it. */ - - base_section_offsets = section_offsets; - baseaddr = ANOFFSET (section_offsets, 0); - - /* Follow the compilation unit sibling chain, building a partial symbol - table entry for each one. Save enough information about each compilation - unit to locate the full DWARF information later. */ - - scan_compilation_units (dbbase, dbbase + dbsize, dbfoff, lnoffset, objfile); - - do_cleanups (back_to); - current_objfile = NULL; -} - -/* - -LOCAL FUNCTION - - read_lexical_block_scope -- process all dies in a lexical block - -SYNOPSIS - - static void read_lexical_block_scope (struct dieinfo *dip, - char *thisdie, char *enddie) - -DESCRIPTION - - 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 (dip, thisdie, enddie, objfile) - struct dieinfo *dip; - char *thisdie; - char *enddie; - struct objfile *objfile; -{ - register struct context_stack *new; - - push_context (0, dip -> at_low_pc); - process_dies (thisdie + dip -> die_length, enddie, objfile); - new = pop_context (); - if (local_symbols != NULL) - { - finish_block (0, &local_symbols, new -> old_blocks, new -> start_addr, - dip -> at_high_pc, objfile); - } - local_symbols = new -> locals; -} - -/* - -LOCAL FUNCTION - - lookup_utype -- look up a user defined type from die reference - -SYNOPSIS - - static type *lookup_utype (DIE_REF die_ref) - -DESCRIPTION - - Given a DIE reference, lookup the user defined type associated with - that DIE, if it has been registered already. If not registered, then - return NULL. Alloc_utype() can be called to register an empty - type for this reference, which will be filled in later when the - actual referenced DIE is processed. - */ - -static struct type * -lookup_utype (die_ref) - DIE_REF die_ref; -{ - struct type *type = NULL; - int utypeidx; - - utypeidx = (die_ref - dbroff) / 4; - if ((utypeidx < 0) || (utypeidx >= numutypes)) - { - complain (&bad_die_ref, DIE_ID, DIE_NAME); - } - else - { - type = *(utypes + utypeidx); - } - return (type); -} - - -/* - -LOCAL FUNCTION - - alloc_utype -- add a user defined type for die reference - -SYNOPSIS - - static type *alloc_utype (DIE_REF die_ref, struct type *utypep) - -DESCRIPTION - - Given a die reference DIE_REF, and a possible pointer to a user - defined type UTYPEP, register that this reference has a user - defined type and either use the specified type in UTYPEP or - make a new empty type that will be filled in later. - - We should only be called after calling lookup_utype() to verify that - there is not currently a type registered for DIE_REF. - */ - -static struct type * -alloc_utype (die_ref, utypep) - DIE_REF die_ref; - struct type *utypep; -{ - struct type **typep; - int utypeidx; - - utypeidx = (die_ref - dbroff) / 4; - typep = utypes + utypeidx; - if ((utypeidx < 0) || (utypeidx >= numutypes)) - { - utypep = dwarf_fundamental_type (current_objfile, FT_INTEGER); - complain (&bad_die_ref, DIE_ID, DIE_NAME); - } - else if (*typep != NULL) - { - utypep = *typep; - complain (&dup_user_type_allocation, DIE_ID, DIE_NAME); - } - else - { - if (utypep == NULL) - { - utypep = alloc_type (current_objfile); - } - *typep = utypep; - } - return (utypep); -} - -/* - -LOCAL FUNCTION - - decode_die_type -- return a type for a specified die - -SYNOPSIS - - static struct type *decode_die_type (struct dieinfo *dip) - -DESCRIPTION - - Given a pointer to a die information structure DIP, decode the - type of the die and return a pointer to the decoded type. All - dies without specific types default to type int. - */ - -static struct type * -decode_die_type (dip) - struct dieinfo *dip; -{ - struct type *type = NULL; - - if (dip -> at_fund_type != 0) - { - type = decode_fund_type (dip -> at_fund_type); - } - else if (dip -> at_mod_fund_type != NULL) - { - type = decode_mod_fund_type (dip -> at_mod_fund_type); - } - else if (dip -> at_user_def_type) - { - if ((type = lookup_utype (dip -> at_user_def_type)) == NULL) - { - type = alloc_utype (dip -> at_user_def_type, NULL); - } - } - else if (dip -> at_mod_u_d_type) - { - type = decode_mod_u_d_type (dip -> at_mod_u_d_type); - } - else - { - type = dwarf_fundamental_type (current_objfile, FT_INTEGER); - } - return (type); -} - -/* - -LOCAL FUNCTION - - struct_type -- compute and return the type for a struct or union - -SYNOPSIS - - static struct type *struct_type (struct dieinfo *dip, char *thisdie, - char *enddie, struct objfile *objfile) - -DESCRIPTION - - Given pointer to a die information structure for a die which - defines a union or structure (and MUST define one or the other), - and pointers to the raw die data that define the range of dies which - define the members, compute and return the user defined type for the - structure or union. - */ - -static struct type * -struct_type (dip, thisdie, enddie, objfile) - struct dieinfo *dip; - char *thisdie; - char *enddie; - struct objfile *objfile; -{ - struct type *type; - struct nextfield { - struct nextfield *next; - struct field field; - }; - struct nextfield *list = NULL; - struct nextfield *new; - int nfields = 0; - int n; - struct dieinfo mbr; - char *nextdie; -#if !BITS_BIG_ENDIAN - int anonymous_size; -#endif - - if ((type = lookup_utype (dip -> die_ref)) == NULL) - { - /* No forward references created an empty type, so install one now */ - type = alloc_utype (dip -> die_ref, NULL); - } - INIT_CPLUS_SPECIFIC(type); - switch (dip -> die_tag) - { - case TAG_class_type: - TYPE_CODE (type) = TYPE_CODE_CLASS; - break; - case TAG_structure_type: - TYPE_CODE (type) = TYPE_CODE_STRUCT; - break; - case TAG_union_type: - TYPE_CODE (type) = TYPE_CODE_UNION; - break; - default: - /* Should never happen */ - TYPE_CODE (type) = TYPE_CODE_UNDEF; - complain (&missing_tag, DIE_ID, DIE_NAME); - break; - } - /* Some compilers try to be helpful by inventing "fake" names for - anonymous enums, structures, and unions, like "~0fake" or ".0fake". - Thanks, but no thanks... */ - if (dip -> at_name != NULL - && *dip -> at_name != '~' - && *dip -> at_name != '.') - { - TYPE_TAG_NAME (type) = obconcat (&objfile -> type_obstack, - "", "", dip -> at_name); - } - /* Use whatever size is known. Zero is a valid size. We might however - wish to check has_at_byte_size to make sure that some byte size was - given explicitly, but DWARF doesn't specify that explicit sizes of - zero have to present, so complaining about missing sizes should - probably not be the default. */ - TYPE_LENGTH (type) = dip -> at_byte_size; - thisdie += dip -> die_length; - while (thisdie < enddie) - { - basicdieinfo (&mbr, thisdie, objfile); - completedieinfo (&mbr, objfile); - if (mbr.die_length <= SIZEOF_DIE_LENGTH) - { - break; - } - else if (mbr.at_sibling != 0) - { - nextdie = dbbase + mbr.at_sibling - dbroff; - } - else - { - nextdie = thisdie + mbr.die_length; - } - switch (mbr.die_tag) - { - case TAG_member: - /* Get space to record the next field's data. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new -> next = list; - list = new; - /* Save the data. */ - 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); - /* Handle bit fields. */ - list -> field.bitsize = mbr.at_bit_size; -#if BITS_BIG_ENDIAN - /* For big endian bits, the 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. */ - list -> field.bitpos += mbr.at_bit_offset; -#else - /* For little endian bits, we need to have a non-zero at_bit_size, - so that we know we are in fact dealing with a bitfield. 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. */ - if (mbr.at_bit_size > 0) - { - if (mbr.has_at_byte_size) - { - /* The size of the anonymous object containing the bit field - is explicit, so use the indicated size (in bytes). */ - anonymous_size = mbr.at_byte_size; - } - else - { - /* The size of the anonymous object containing the bit field - matches the size of an object of the bit field's type. - DWARF allows at_byte_size to be left out in such cases, - as a debug information size optimization. */ - anonymous_size = TYPE_LENGTH (list -> field.type); - } - list -> field.bitpos += - anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size; - } -#endif - nfields++; - break; - default: - process_dies (thisdie, nextdie, objfile); - break; - } - thisdie = nextdie; - } - /* Now create the vector of fields, and record how big it is. We may - not even have any fields, if this DIE was generated due to a reference - to an anonymous structure or union. In this case, TYPE_FLAG_STUB is - set, which clues gdb in to the fact that it needs to search elsewhere - for the full structure definition. */ - if (nfields == 0) - { - TYPE_FLAGS (type) |= TYPE_FLAG_STUB; - } - else - { - TYPE_NFIELDS (type) = nfields; - TYPE_FIELDS (type) = (struct field *) - TYPE_ALLOC (type, sizeof (struct field) * nfields); - /* Copy the saved-up fields into the field vector. */ - for (n = nfields; list; list = list -> next) - { - TYPE_FIELD (type, --n) = list -> field; - } - } - return (type); -} - -/* - -LOCAL FUNCTION - - read_structure_scope -- process all dies within struct or union - -SYNOPSIS - - static void read_structure_scope (struct dieinfo *dip, - char *thisdie, char *enddie, struct objfile *objfile) - -DESCRIPTION - - 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. DIP is a pointer to the die info - struct for the DIE that names the structure or union. - -NOTES - - Note that 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 (dip, thisdie, enddie, objfile) - struct dieinfo *dip; - char *thisdie; - char *enddie; - struct objfile *objfile; -{ - struct type *type; - struct symbol *sym; - - type = struct_type (dip, thisdie, enddie, objfile); - if (!(TYPE_FLAGS (type) & TYPE_FLAG_STUB)) - { - sym = new_symbol (dip, objfile); - if (sym != NULL) - { - SYMBOL_TYPE (sym) = type; - if (cu_language == language_cplus) - { - synthesize_typedef (dip, objfile, type); - } - } - } -} - -/* - -LOCAL FUNCTION - - decode_array_element_type -- decode type of the array elements - -SYNOPSIS - - static struct type *decode_array_element_type (char *scan, char *end) - -DESCRIPTION - - As the last step in decoding the array subscript information for an - array DIE, we need to decode the type of the array elements. We are - passed a pointer to this last part of the subscript information and - must return the appropriate type. If the type attribute is not - recognized, just warn about the problem and return type int. - */ - -static struct type * -decode_array_element_type (scan) - char *scan; -{ - struct type *typep; - DIE_REF die_ref; - unsigned short attribute; - unsigned short fundtype; - int nbytes; - - attribute = target_to_host (scan, SIZEOF_ATTRIBUTE, GET_UNSIGNED, - current_objfile); - scan += SIZEOF_ATTRIBUTE; - if ((nbytes = attribute_size (attribute)) == -1) - { - complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute); - typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); - } - else - { - switch (attribute) - { - case AT_fund_type: - fundtype = target_to_host (scan, nbytes, GET_UNSIGNED, - current_objfile); - typep = decode_fund_type (fundtype); - break; - case AT_mod_fund_type: - typep = decode_mod_fund_type (scan); - break; - case AT_user_def_type: - die_ref = target_to_host (scan, nbytes, GET_UNSIGNED, - current_objfile); - if ((typep = lookup_utype (die_ref)) == NULL) - { - typep = alloc_utype (die_ref, NULL); - } - break; - case AT_mod_u_d_type: - typep = decode_mod_u_d_type (scan); - break; - default: - complain (&bad_array_element_type, DIE_ID, DIE_NAME, attribute); - typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); - break; - } - } - return (typep); -} - -/* - -LOCAL FUNCTION - - decode_subscript_data_item -- decode array subscript item - -SYNOPSIS - - static struct type * - decode_subscript_data_item (char *scan, char *end) - -DESCRIPTION - - The array subscripts and the data type of the elements of an - array are described by a list of data items, stored as a block - of contiguous bytes. There is a data item describing each array - dimension, and a final data item describing the element type. - The data items are ordered the same as their appearance in the - source (I.E. leftmost dimension first, next to leftmost second, - etc). - - The data items describing each array dimension consist of four - parts: (1) a format specifier, (2) type type of the subscript - index, (3) a description of the low bound of the array dimension, - and (4) a description of the high bound of the array dimension. - - The last data item is the description of the type of each of - the array elements. - - We are passed a pointer to the start of the block of bytes - containing the remaining data items, and a pointer to the first - byte past the data. This function recursively decodes the - remaining data items and returns a type. - - If we somehow fail to decode some data, we complain about it - and return a type "array of int". - -BUGS - FIXME: This code only implements the forms currently used - by the AT&T and GNU C compilers. - - The end pointer is supplied for error checking, maybe we should - use it for that... - */ - -static struct type * -decode_subscript_data_item (scan, end) - char *scan; - char *end; -{ - struct type *typep = NULL; /* Array type we are building */ - struct type *nexttype; /* Type of each element (may be array) */ - struct type *indextype; /* Type of this index */ - struct type *rangetype; - unsigned int format; - unsigned short fundtype; - unsigned long lowbound; - unsigned long highbound; - int nbytes; - - format = target_to_host (scan, SIZEOF_FORMAT_SPECIFIER, GET_UNSIGNED, - current_objfile); - scan += SIZEOF_FORMAT_SPECIFIER; - switch (format) - { - case FMT_ET: - typep = decode_array_element_type (scan); - break; - case FMT_FT_C_C: - fundtype = target_to_host (scan, SIZEOF_FMT_FT, GET_UNSIGNED, - current_objfile); - indextype = decode_fund_type (fundtype); - scan += SIZEOF_FMT_FT; - nbytes = TARGET_FT_LONG_SIZE (current_objfile); - lowbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile); - scan += nbytes; - highbound = target_to_host (scan, nbytes, GET_UNSIGNED, current_objfile); - scan += nbytes; - nexttype = decode_subscript_data_item (scan, end); - if (nexttype == NULL) - { - /* Munged subscript data or other problem, fake it. */ - complain (&subscript_data_items, DIE_ID, DIE_NAME); - nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER); - } - rangetype = create_range_type ((struct type *) NULL, indextype, - lowbound, highbound); - typep = create_array_type ((struct type *) NULL, nexttype, rangetype); - break; - case FMT_FT_C_X: - case FMT_FT_X_C: - case FMT_FT_X_X: - case FMT_UT_C_C: - case FMT_UT_C_X: - case FMT_UT_X_C: - case FMT_UT_X_X: - complain (&unhandled_array_subscript_format, DIE_ID, DIE_NAME, format); - nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER); - rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0); - typep = create_array_type ((struct type *) NULL, nexttype, rangetype); - break; - default: - complain (&unknown_array_subscript_format, DIE_ID, DIE_NAME, format); - nexttype = dwarf_fundamental_type (current_objfile, FT_INTEGER); - rangetype = create_range_type ((struct type *) NULL, nexttype, 0, 0); - typep = create_array_type ((struct type *) NULL, nexttype, rangetype); - break; - } - return (typep); -} - -/* - -LOCAL FUNCTION - - dwarf_read_array_type -- read TAG_array_type DIE - -SYNOPSIS - - static void dwarf_read_array_type (struct dieinfo *dip) - -DESCRIPTION - - Extract all information from a TAG_array_type DIE and add to - the user defined type vector. - */ - -static void -dwarf_read_array_type (dip) - struct dieinfo *dip; -{ - struct type *type; - struct type *utype; - char *sub; - char *subend; - unsigned short blocksz; - int nbytes; - - if (dip -> at_ordering != ORD_row_major) - { - /* FIXME: Can gdb even handle column major arrays? */ - complain (¬_row_major, DIE_ID, DIE_NAME); - } - if ((sub = dip -> at_subscr_data) != NULL) - { - nbytes = attribute_size (AT_subscr_data); - blocksz = target_to_host (sub, nbytes, GET_UNSIGNED, current_objfile); - subend = sub + nbytes + blocksz; - sub += nbytes; - type = decode_subscript_data_item (sub, subend); - if ((utype = lookup_utype (dip -> die_ref)) == NULL) - { - /* Install user defined type that has not been referenced yet. */ - alloc_utype (dip -> die_ref, type); - } - else if (TYPE_CODE (utype) == TYPE_CODE_UNDEF) - { - /* Ick! A forward ref has already generated a blank type in our - slot, and this type probably already has things pointing to it - (which is what caused it to be created in the first place). - If it's just a place holder we can plop our fully defined type - on top of it. We can't recover the space allocated for our - new type since it might be on an obstack, but we could reuse - it if we kept a list of them, but it might not be worth it - (FIXME). */ - *utype = *type; - } - else - { - /* Double ick! Not only is a type already in our slot, but - someone has decorated it. Complain and leave it alone. */ - complain (&dup_user_type_definition, DIE_ID, DIE_NAME); - } - } -} - -/* - -LOCAL FUNCTION - - read_tag_pointer_type -- read TAG_pointer_type DIE - -SYNOPSIS - - static void read_tag_pointer_type (struct dieinfo *dip) - -DESCRIPTION - - Extract all information from a TAG_pointer_type DIE and add to - the user defined type vector. - */ - -static void -read_tag_pointer_type (dip) - struct dieinfo *dip; -{ - struct type *type; - struct type *utype; - - type = decode_die_type (dip); - if ((utype = lookup_utype (dip -> die_ref)) == NULL) - { - utype = lookup_pointer_type (type); - alloc_utype (dip -> die_ref, utype); - } - else - { - TYPE_TARGET_TYPE (utype) = type; - 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 *); - TYPE_CODE (utype) = TYPE_CODE_PTR; - } -} - -/* - -LOCAL FUNCTION - - read_tag_string_type -- read TAG_string_type DIE - -SYNOPSIS - - static void read_tag_string_type (struct dieinfo *dip) - -DESCRIPTION - - Extract all information from a 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 (dip) - struct dieinfo *dip; -{ - struct type *utype; - struct type *indextype; - struct type *rangetype; - unsigned long lowbound = 0; - unsigned long highbound; - - if (dip -> has_at_byte_size) - { - /* A fixed bounds string */ - highbound = dip -> at_byte_size - 1; - } - else - { - /* A varying length string. Stub for now. (FIXME) */ - highbound = 1; - } - indextype = dwarf_fundamental_type (current_objfile, FT_INTEGER); - rangetype = create_range_type ((struct type *) NULL, indextype, lowbound, - highbound); - - utype = lookup_utype (dip -> die_ref); - if (utype == NULL) - { - /* No type defined, go ahead and create a blank one to use. */ - utype = alloc_utype (dip -> die_ref, (struct type *) NULL); - } - else - { - /* Already a type in our slot due to a forward reference. Make sure it - is a blank one. If not, complain and leave it alone. */ - if (TYPE_CODE (utype) != TYPE_CODE_UNDEF) - { - complain (&dup_user_type_definition, DIE_ID, DIE_NAME); - return; - } - } - - /* Create the string type using the blank type we either found or created. */ - utype = create_string_type (utype, rangetype); -} - -/* - -LOCAL FUNCTION - - read_subroutine_type -- process TAG_subroutine_type dies - -SYNOPSIS - - static void read_subroutine_type (struct dieinfo *dip, char thisdie, - char *enddie) - -DESCRIPTION - - Handle DIES due to C code like: - - struct foo { - int (*funcp)(int a, long l); (Generates TAG_subroutine_type DIE) - int b; - }; - -NOTES - - The parameter DIES are currently ignored. See if gdb has a way to - include this info in it's type system, and decode them if so. Is - this what the type structure's "arg_types" field is for? (FIXME) - */ - -static void -read_subroutine_type (dip, thisdie, enddie) - struct dieinfo *dip; - char *thisdie; - char *enddie; -{ - struct type *type; /* Type that this function returns */ - struct type *ftype; /* Function that returns above type */ - - /* Decode the type that this subroutine returns */ - - type = decode_die_type (dip); - - /* Check to see if we already have a partially constructed user - defined type for this DIE, from a forward reference. */ - - if ((ftype = lookup_utype (dip -> die_ref)) == NULL) - { - /* This is the first reference to one of these types. Make - a new one and place it in the user defined types. */ - ftype = lookup_function_type (type); - alloc_utype (dip -> die_ref, ftype); - } - else if (TYPE_CODE (ftype) == TYPE_CODE_UNDEF) - { - /* We have an existing partially constructed type, so bash it - into the correct type. */ - TYPE_TARGET_TYPE (ftype) = type; - TYPE_FUNCTION_TYPE (type) = ftype; - TYPE_LENGTH (ftype) = 1; - TYPE_CODE (ftype) = TYPE_CODE_FUNC; - } - else - { - complain (&dup_user_type_definition, DIE_ID, DIE_NAME); - } -} - -/* - -LOCAL FUNCTION - - read_enumeration -- process dies which define an enumeration - -SYNOPSIS - - static void read_enumeration (struct dieinfo *dip, char *thisdie, - char *enddie, struct objfile *objfile) - -DESCRIPTION - - Given a pointer to a die which begins an enumeration, process all - the dies that define the members of the enumeration. - -NOTES - - Note that we need to call enum_type regardless of whether or not we - have a symbol, since we might have an enum without a tag name (thus - no symbol for the tagname). - */ - -static void -read_enumeration (dip, thisdie, enddie, objfile) - struct dieinfo *dip; - char *thisdie; - char *enddie; - struct objfile *objfile; -{ - struct type *type; - struct symbol *sym; - - type = enum_type (dip, objfile); - sym = new_symbol (dip, objfile); - if (sym != NULL) - { - SYMBOL_TYPE (sym) = type; - if (cu_language == language_cplus) - { - synthesize_typedef (dip, objfile, type); - } - } -} - -/* - -LOCAL FUNCTION - - enum_type -- decode and return a type for an enumeration - -SYNOPSIS - - static type *enum_type (struct dieinfo *dip, struct objfile *objfile) - -DESCRIPTION - - Given a pointer to a die information structure for the die which - starts an enumeration, process all the dies that define the members - of the enumeration and return a type pointer for the enumeration. - - At the same time, for each member of the enumeration, create a - symbol for it with namespace VAR_NAMESPACE and class LOC_CONST, - and give it the type of the enumeration itself. - -NOTES - - Note that the DWARF specification explicitly mandates that enum - constants occur in reverse order from the source program order, - for "consistency" and because this ordering is easier for many - compilers to generate. (Draft 6, sec 3.8.5, Enumeration type - Entries). Because gdb wants to see the enum members in program - source order, we have to ensure that the order gets reversed while - we are processing them. - */ - -static struct type * -enum_type (dip, objfile) - struct dieinfo *dip; - struct objfile *objfile; -{ - struct type *type; - struct nextfield { - struct nextfield *next; - struct field field; - }; - struct nextfield *list = NULL; - struct nextfield *new; - int nfields = 0; - int n; - char *scan; - char *listend; - unsigned short blocksz; - struct symbol *sym; - int nbytes; - - if ((type = lookup_utype (dip -> die_ref)) == NULL) - { - /* No forward references created an empty type, so install one now */ - type = alloc_utype (dip -> die_ref, NULL); - } - TYPE_CODE (type) = TYPE_CODE_ENUM; - /* Some compilers try to be helpful by inventing "fake" names for - anonymous enums, structures, and unions, like "~0fake" or ".0fake". - Thanks, but no thanks... */ - if (dip -> at_name != NULL - && *dip -> at_name != '~' - && *dip -> at_name != '.') - { - TYPE_TAG_NAME (type) = obconcat (&objfile -> type_obstack, - "", "", dip -> at_name); - } - if (dip -> at_byte_size != 0) - { - TYPE_LENGTH (type) = dip -> at_byte_size; - } - if ((scan = dip -> at_element_list) != NULL) - { - if (dip -> short_element_list) - { - nbytes = attribute_size (AT_short_element_list); - } - else - { - nbytes = attribute_size (AT_element_list); - } - blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile); - listend = scan + nbytes + blocksz; - scan += nbytes; - while (scan < listend) - { - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new -> next = list; - list = new; - list -> field.type = NULL; - list -> field.bitsize = 0; - list -> field.bitpos = - target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED, - objfile); - scan += TARGET_FT_LONG_SIZE (objfile); - list -> field.name = obsavestring (scan, strlen (scan), - &objfile -> type_obstack); - scan += strlen (scan) + 1; - nfields++; - /* Handcraft a new symbol for this enum member. */ - sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = create_name (list -> field.name, - &objfile->symbol_obstack); - SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language); - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_TYPE (sym) = type; - SYMBOL_VALUE (sym) = list -> field.bitpos; - add_symbol_to_list (sym, list_in_scope); - } - /* Now create the vector of fields, and record how big it is. This is - where we reverse the order, by pulling the members off the list in - reverse order from how they were inserted. If we have no fields - (this is apparently possible in C++) then skip building a field - vector. */ - if (nfields > 0) - { - TYPE_NFIELDS (type) = nfields; - TYPE_FIELDS (type) = (struct field *) - obstack_alloc (&objfile->symbol_obstack, sizeof (struct field) * nfields); - /* Copy the saved-up fields into the field vector. */ - for (n = 0; (n < nfields) && (list != NULL); list = list -> next) - { - TYPE_FIELD (type, n++) = list -> field; - } - } - } - return (type); -} - -/* - -LOCAL FUNCTION - - read_func_scope -- process all dies within a function scope - -DESCRIPTION - - Process all dies within a given function scope. We are passed - a die information structure pointer DIP for the die which - starts the function scope, and pointers into the raw die data - that define the dies within the function scope. - - For now, we ignore lexical block scopes within the function. - The problem is that AT&T cc does not define a DWARF lexical - block scope for the function itself, while gcc defines a - lexical block scope for the function. We need to think about - how to handle this difference, or if it is even a problem. - (FIXME) - */ - -static void -read_func_scope (dip, thisdie, enddie, objfile) - struct dieinfo *dip; - char *thisdie; - char *enddie; - struct objfile *objfile; -{ - register struct context_stack *new; - - if (objfile -> ei.entry_point >= dip -> at_low_pc && - objfile -> ei.entry_point < dip -> at_high_pc) - { - objfile -> ei.entry_func_lowpc = dip -> at_low_pc; - objfile -> ei.entry_func_highpc = dip -> at_high_pc; - } - if (STREQ (dip -> at_name, "main")) /* FIXME: hardwired name */ - { - objfile -> ei.main_func_lowpc = dip -> at_low_pc; - objfile -> ei.main_func_highpc = dip -> at_high_pc; - } - new = push_context (0, dip -> at_low_pc); - new -> name = new_symbol (dip, objfile); - list_in_scope = &local_symbols; - process_dies (thisdie + dip -> die_length, enddie, objfile); - new = pop_context (); - /* Make a block for the local symbols within. */ - finish_block (new -> name, &local_symbols, new -> old_blocks, - new -> start_addr, dip -> at_high_pc, objfile); - list_in_scope = &file_symbols; -} - - -/* - -LOCAL FUNCTION - - handle_producer -- process the AT_producer attribute - -DESCRIPTION - - Perform any operations that depend on finding a particular - AT_producer attribute. - - */ - -static void -handle_producer (producer) - char *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)); - - /* 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 - is not auto. We also leave the demangling style alone if we find a - gcc (cc1) producer, as opposed to a g++ (cc1plus) producer. */ - - if (AUTO_DEMANGLING) - { - if (STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))) - { - set_demangling_style (GNU_DEMANGLING_STYLE_STRING); - } - else if (STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER))) - { - set_demangling_style (LUCID_DEMANGLING_STYLE_STRING); - } - } -} - - -/* - -LOCAL FUNCTION - - read_file_scope -- process all dies within a file scope - -DESCRIPTION - - Process all dies within a given file scope. We are passed a - pointer to the die information structure for the die which - starts the file scope, and pointers into the raw die data which - mark the range of dies within the file scope. - - When the partial symbol table is built, the file offset for the line - number table for each compilation unit is saved in the partial symbol - table entry for that compilation unit. As the symbols for each - compilation unit are read, the line number table is read into memory - and the variable lnbase is set to point to it. Thus all we have to - do is use lnbase to access the line number table for the current - compilation unit. - */ - -static void -read_file_scope (dip, thisdie, enddie, objfile) - struct dieinfo *dip; - char *thisdie; - char *enddie; - struct objfile *objfile; -{ - struct cleanup *back_to; - struct symtab *symtab; - - if (objfile -> ei.entry_point >= dip -> at_low_pc && - objfile -> ei.entry_point < dip -> at_high_pc) - { - objfile -> ei.entry_file_lowpc = dip -> at_low_pc; - objfile -> ei.entry_file_highpc = dip -> at_high_pc; - } - set_cu_language (dip); - if (dip -> at_producer != NULL) - { - handle_producer (dip -> at_producer); - } - numutypes = (enddie - thisdie) / 4; - utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *)); - back_to = make_cleanup (free, utypes); - 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); - decode_line_numbers (lnbase); - process_dies (thisdie + dip -> die_length, enddie, objfile); - - symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile, 0); - if (symtab != NULL) - { - symtab -> language = cu_language; - } - do_cleanups (back_to); - utypes = NULL; - numutypes = 0; -} - -/* - -LOCAL FUNCTION - - process_dies -- process a range of DWARF Information Entries - -SYNOPSIS - - static void process_dies (char *thisdie, char *enddie, - struct objfile *objfile) - -DESCRIPTION - - Process all DIE's in a specified range. May be (and almost - certainly will be) called recursively. - */ - -static void -process_dies (thisdie, enddie, objfile) - char *thisdie; - char *enddie; - struct objfile *objfile; -{ - char *nextdie; - struct dieinfo di; - - while (thisdie < enddie) - { - basicdieinfo (&di, thisdie, objfile); - if (di.die_length < SIZEOF_DIE_LENGTH) - { - break; - } - else if (di.die_tag == TAG_padding) - { - nextdie = thisdie + di.die_length; - } - else - { - completedieinfo (&di, objfile); - if (di.at_sibling != 0) - { - nextdie = dbbase + di.at_sibling - dbroff; - } - else - { - nextdie = thisdie + di.die_length; - } -#ifdef SMASH_TEXT_ADDRESS - /* I think that these are always text, not data, addresses. */ - SMASH_TEXT_ADDRESS (di.at_low_pc); - SMASH_TEXT_ADDRESS (di.at_high_pc); -#endif - switch (di.die_tag) - { - case TAG_compile_unit: - /* Skip Tag_compile_unit if we are already inside a compilation - unit, we are unable to handle nested compilation units - properly (FIXME). */ - if (current_subfile == NULL) - read_file_scope (&di, thisdie, nextdie, objfile); - else - nextdie = thisdie + di.die_length; - break; - case TAG_global_subroutine: - case TAG_subroutine: - if (di.has_at_low_pc) - { - read_func_scope (&di, thisdie, nextdie, objfile); - } - break; - case TAG_lexical_block: - read_lexical_block_scope (&di, thisdie, nextdie, objfile); - break; - case TAG_class_type: - case TAG_structure_type: - case TAG_union_type: - read_structure_scope (&di, thisdie, nextdie, objfile); - break; - case TAG_enumeration_type: - read_enumeration (&di, thisdie, nextdie, objfile); - break; - case TAG_subroutine_type: - read_subroutine_type (&di, thisdie, nextdie); - break; - case TAG_array_type: - dwarf_read_array_type (&di); - break; - case TAG_pointer_type: - read_tag_pointer_type (&di); - break; - case TAG_string_type: - read_tag_string_type (&di); - break; - default: - new_symbol (&di, objfile); - break; - } - } - thisdie = nextdie; - } -} - -/* - -LOCAL FUNCTION - - decode_line_numbers -- decode a line number table fragment - -SYNOPSIS - - static void decode_line_numbers (char *tblscan, char *tblend, - long length, long base, long line, long pc) - -DESCRIPTION - - Translate the DWARF line number information to gdb form. - - The ".line" section contains one or more line number tables, one for - each ".line" section from the objects that were linked. - - The AT_stmt_list attribute for each TAG_source_file entry in the - ".debug" section contains the offset into the ".line" section for the - start of the table for that file. - - The table itself has the following structure: - - - 4 bytes 4 bytes 10 bytes - - The table length is the total size of the table, including the 4 bytes - for the length information. - - The base address is the address of the first instruction generated - for the source file. - - Each source statement entry has the following structure: - -
- 4 bytes 2 bytes 4 bytes - - The line number is relative to the start of the file, starting with - line 1. - - The statement position either -1 (0xFFFF) or the number of characters - from the beginning of the line to the beginning of the statement. - - The address delta is the difference between the base address and - the address of the first instruction for the statement. - - Note that we must copy the bytes from the packed table to our local - variables before attempting to use them, to avoid alignment problems - on some machines, particularly RISC processors. - -BUGS - - Does gdb expect the line numbers to be sorted? They are now by - chance/luck, but are not required to be. (FIXME) - - The line with number 0 is unused, gdb apparently can discover the - span of the last line some other way. How? (FIXME) - */ - -static void -decode_line_numbers (linetable) - char *linetable; -{ - char *tblscan; - char *tblend; - unsigned long length; - unsigned long base; - unsigned long line; - unsigned long pc; - - if (linetable != NULL) - { - tblscan = tblend = linetable; - length = target_to_host (tblscan, SIZEOF_LINETBL_LENGTH, GET_UNSIGNED, - current_objfile); - tblscan += SIZEOF_LINETBL_LENGTH; - tblend += length; - base = target_to_host (tblscan, TARGET_FT_POINTER_SIZE (objfile), - GET_UNSIGNED, current_objfile); - tblscan += TARGET_FT_POINTER_SIZE (objfile); - base += baseaddr; - while (tblscan < tblend) - { - line = target_to_host (tblscan, SIZEOF_LINETBL_LINENO, GET_UNSIGNED, - current_objfile); - tblscan += SIZEOF_LINETBL_LINENO + SIZEOF_LINETBL_STMT; - pc = target_to_host (tblscan, SIZEOF_LINETBL_DELTA, GET_UNSIGNED, - current_objfile); - tblscan += SIZEOF_LINETBL_DELTA; - pc += base; - if (line != 0) - { - record_line (current_subfile, line, pc); - } - } - } -} - -/* - -LOCAL FUNCTION - - locval -- compute the value of a location attribute - -SYNOPSIS - - static int locval (char *loc) - -DESCRIPTION - - Given pointer to a string of bytes that define a location, compute - the location and return the value. - - 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 - 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. - -NOTES - - Note that stack[0] is unused except as a default error return. - Note that stack overflow is not yet handled. - */ - -static int -locval (loc) - char *loc; -{ - unsigned short nbytes; - unsigned short locsize; - auto long stack[64]; - int stacki; - char *end; - int loc_atom_code; - int loc_value_size; - - 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; - loc_value_size = TARGET_FT_LONG_SIZE (current_objfile); - while (loc < end) - { - loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED, - current_objfile); - loc += SIZEOF_LOC_ATOM_CODE; - switch (loc_atom_code) - { - case 0: - /* error */ - loc = end; - break; - case OP_REG: - /* push register (number) */ - stack[++stacki] = target_to_host (loc, loc_value_size, - GET_UNSIGNED, current_objfile); - loc += loc_value_size; - 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); - loc += loc_value_size; - stack[++stacki] = 0; - break; - case OP_ADDR: - /* push address (relocated address) */ - stack[++stacki] = target_to_host (loc, loc_value_size, - GET_UNSIGNED, current_objfile); - loc += loc_value_size; - break; - case OP_CONST: - /* push constant (number) FIXME: signed or unsigned! */ - stack[++stacki] = target_to_host (loc, loc_value_size, - GET_SIGNED, current_objfile); - loc += loc_value_size; - break; - case OP_DEREF2: - /* pop, deref and push 2 bytes (as a long) */ - complain (&op_deref2, DIE_ID, DIE_NAME, stack[stacki]); - break; - case OP_DEREF4: /* pop, deref and push 4 bytes (as a long) */ - complain (&op_deref4, DIE_ID, DIE_NAME, stack[stacki]); - break; - case OP_ADD: /* pop top 2 items, add, push result */ - stack[stacki - 1] += stack[stacki]; - stacki--; - break; - } - } - return (stack[stacki]); -} - -/* - -LOCAL FUNCTION - - read_ofile_symtab -- build a full symtab entry from chunk of DIE's - -SYNOPSIS - - static void read_ofile_symtab (struct partial_symtab *pst) - -DESCRIPTION - - When expanding a partial symbol table entry to a full symbol table - entry, this is the function that gets called to read in the symbols - for the compilation unit. A pointer to the newly constructed symtab, - which is now the new first one on the objfile's symtab list, is - stashed in the partial symbol table entry. - */ - -static void -read_ofile_symtab (pst) - struct partial_symtab *pst; -{ - struct cleanup *back_to; - unsigned long lnsize; - file_ptr foffset; - bfd *abfd; - char lnsizedata[SIZEOF_LINETBL_LENGTH]; - - abfd = pst -> objfile -> obfd; - current_objfile = pst -> objfile; - - /* Allocate a buffer for the entire chunk of DIE's for this compilation - unit, seek to the location in the file, and read in all the DIE's. */ - - diecount = 0; - dbsize = DBLENGTH (pst); - dbbase = xmalloc (dbsize); - dbroff = DBROFF(pst); - foffset = DBFOFF(pst) + dbroff; - base_section_offsets = pst->section_offsets; - baseaddr = ANOFFSET (pst->section_offsets, 0); - if (bfd_seek (abfd, foffset, L_SET) || - (bfd_read (dbbase, dbsize, 1, abfd) != dbsize)) - { - free (dbbase); - error ("can't read DWARF data"); - } - back_to = make_cleanup (free, dbbase); - - /* If there is a line number table associated with this compilation unit - then read the size of this fragment in bytes, from the fragment itself. - Allocate a buffer for the fragment and read it in for future - processing. */ - - lnbase = NULL; - if (LNFOFF (pst)) - { - if (bfd_seek (abfd, LNFOFF (pst), L_SET) || - (bfd_read ((PTR) lnsizedata, sizeof (lnsizedata), 1, abfd) != - sizeof (lnsizedata))) - { - error ("can't read DWARF line number table size"); - } - lnsize = target_to_host (lnsizedata, SIZEOF_LINETBL_LENGTH, - GET_UNSIGNED, pst -> objfile); - lnbase = xmalloc (lnsize); - if (bfd_seek (abfd, LNFOFF (pst), L_SET) || - (bfd_read (lnbase, lnsize, 1, abfd) != lnsize)) - { - free (lnbase); - error ("can't read DWARF line numbers"); - } - make_cleanup (free, lnbase); - } - - process_dies (dbbase, dbbase + dbsize, pst -> objfile); - do_cleanups (back_to); - current_objfile = NULL; - pst -> symtab = pst -> objfile -> symtabs; -} - -/* - -LOCAL FUNCTION - - psymtab_to_symtab_1 -- do grunt work for building a full symtab entry - -SYNOPSIS - - static void psymtab_to_symtab_1 (struct partial_symtab *pst) - -DESCRIPTION - - Called once for each partial symbol table entry that needs to be - expanded into a full symbol table entry. - -*/ - -static void -psymtab_to_symtab_1 (pst) - struct partial_symtab *pst; -{ - int i; - struct cleanup *old_chain; - - if (pst != NULL) - { - if (pst->readin) - { - warning ("psymtab for %s already read in. Shouldn't happen.", - pst -> filename); - } - else - { - /* 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 (""); - gdb_flush (gdb_stdout); /* Flush output */ - } - psymtab_to_symtab_1 (pst -> dependencies[i]); - } - } - if (DBLENGTH (pst)) /* Otherwise it's a dummy */ - { - buildsym_init (); - old_chain = make_cleanup (really_free_pendings, 0); - read_ofile_symtab (pst); - if (info_verbose) - { - printf_filtered ("%d DIE's, sorting...", diecount); - wrap_here (""); - gdb_flush (gdb_stdout); - } - sort_symtab_syms (pst -> symtab); - do_cleanups (old_chain); - } - pst -> readin = 1; - } - } -} - -/* - -LOCAL FUNCTION - - dwarf_psymtab_to_symtab -- build a full symtab entry from partial one - -SYNOPSIS - - static void dwarf_psymtab_to_symtab (struct partial_symtab *pst) - -DESCRIPTION - - This is the DWARF support entry point for building a full symbol - table entry from a partial symbol table entry. We are passed a - pointer to the partial symbol table entry that needs to be expanded. - -*/ - -static void -dwarf_psymtab_to_symtab (pst) - struct partial_symtab *pst; -{ - - if (pst != NULL) - { - if (pst -> readin) - { - warning ("psymtab for %s already read in. Shouldn't happen.", - pst -> filename); - } - else - { - if (DBLENGTH (pst) || pst -> number_of_dependencies) - { - /* Print the message now, before starting serious work, to avoid - disconcerting pauses. */ - if (info_verbose) - { - printf_filtered ("Reading in symbols for %s...", - pst -> filename); - gdb_flush (gdb_stdout); - } - - psymtab_to_symtab_1 (pst); - -#if 0 /* FIXME: Check to see what dbxread is doing here and see if - we need to do an equivalent or is this something peculiar to - stabs/a.out format. - 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); -#endif - - /* Finish up the verbose info message. */ - if (info_verbose) - { - printf_filtered ("done.\n"); - gdb_flush (gdb_stdout); - } - } - } - } -} - -/* - -LOCAL FUNCTION - - init_psymbol_list -- initialize storage for partial symbols - -SYNOPSIS - - static void init_psymbol_list (struct objfile *objfile, int total_symbols) - -DESCRIPTION - - Initializes storage for all of the partial symbols that will be - created by dwarf_build_psymtabs and subsidiaries. - */ - -static void -init_psymbol_list (objfile, total_symbols) - struct objfile *objfile; - int total_symbols; -{ - /* Free any previously allocated psymbol lists. */ - - if (objfile -> global_psymbols.list) - { - mfree (objfile -> md, (PTR)objfile -> global_psymbols.list); - } - if (objfile -> static_psymbols.list) - { - mfree (objfile -> md, (PTR)objfile -> static_psymbols.list); - } - - /* Current best guess is that there are approximately a twentieth - of the total symbols (in a debugging file) are global or static - oriented 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)); -} - -/* - -LOCAL FUNCTION - - add_enum_psymbol -- add enumeration members to partial symbol table - -DESCRIPTION - - Given pointer to a DIE that is known to be for an enumeration, - extract the symbolic names of the enumeration members and add - partial symbols for them. -*/ - -static void -add_enum_psymbol (dip, objfile) - struct dieinfo *dip; - struct objfile *objfile; -{ - char *scan; - char *listend; - unsigned short blocksz; - int nbytes; - - if ((scan = dip -> at_element_list) != NULL) - { - if (dip -> short_element_list) - { - nbytes = attribute_size (AT_short_element_list); - } - else - { - nbytes = attribute_size (AT_element_list); - } - blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile); - scan += nbytes; - listend = scan + blocksz; - while (scan < listend) - { - scan += TARGET_FT_LONG_SIZE (objfile); - ADD_PSYMBOL_TO_LIST (scan, strlen (scan), VAR_NAMESPACE, LOC_CONST, - objfile -> static_psymbols, 0, cu_language, - objfile); - scan += strlen (scan) + 1; - } - } -} - -/* - -LOCAL FUNCTION - - add_partial_symbol -- add symbol to partial symbol table - -DESCRIPTION - - Given a DIE, if it is one of the types that we want to - add to a partial symbol table, finish filling in the die info - and then add a partial symbol table entry for it. - -NOTES - - The caller must ensure that the DIE has a valid name attribute. -*/ - -static void -add_partial_symbol (dip, objfile) - struct dieinfo *dip; - struct objfile *objfile; -{ - switch (dip -> die_tag) - { - case TAG_global_subroutine: - ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), - VAR_NAMESPACE, LOC_BLOCK, - objfile -> global_psymbols, - dip -> at_low_pc, cu_language, objfile); - break; - case TAG_global_variable: - ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), - VAR_NAMESPACE, LOC_STATIC, - objfile -> global_psymbols, - 0, cu_language, objfile); - break; - case TAG_subroutine: - ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), - VAR_NAMESPACE, LOC_BLOCK, - objfile -> static_psymbols, - dip -> at_low_pc, cu_language, objfile); - break; - case TAG_local_variable: - ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), - VAR_NAMESPACE, LOC_STATIC, - objfile -> static_psymbols, - 0, cu_language, objfile); - break; - case TAG_typedef: - ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), - VAR_NAMESPACE, LOC_TYPEDEF, - objfile -> static_psymbols, - 0, cu_language, objfile); - break; - case TAG_class_type: - case TAG_structure_type: - case TAG_union_type: - case TAG_enumeration_type: - /* Do not add opaque aggregate definitions to the psymtab. */ - if (!dip -> has_at_byte_size) - break; - ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), - STRUCT_NAMESPACE, LOC_TYPEDEF, - objfile -> static_psymbols, - 0, cu_language, objfile); - if (cu_language == language_cplus) - { - /* For C++, these implicitly act as typedefs as well. */ - ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name), - VAR_NAMESPACE, LOC_TYPEDEF, - objfile -> static_psymbols, - 0, cu_language, objfile); - } - break; - } -} - -/* - -LOCAL FUNCTION - - scan_partial_symbols -- scan DIE's within a single compilation unit - -DESCRIPTION - - Process the DIE's within a single compilation unit, looking for - interesting DIE's that contribute to the partial symbol table entry - for this compilation unit. - -NOTES - - There are some DIE's that may appear both at file scope and within - the scope of a function. We are only interested in the ones at file - scope, and the only way to tell them apart is to keep track of the - scope. For example, consider the test case: - - static int i; - main () { int j; } - - for which the relevant DWARF segment has the structure: - - 0x51: - 0x23 global subrtn sibling 0x9b - name main - fund_type FT_integer - low_pc 0x800004cc - high_pc 0x800004d4 - - 0x74: - 0x23 local var sibling 0x97 - name j - fund_type FT_integer - location OP_BASEREG 0xe - OP_CONST 0xfffffffc - OP_ADD - 0x97: - 0x4 - - 0x9b: - 0x1d local var sibling 0xb8 - name i - fund_type FT_integer - location OP_ADDR 0x800025dc - - 0xb8: - 0x4 - - We want to include the symbol 'i' in the partial symbol table, but - not the symbol 'j'. In essence, we want to skip all the dies within - the scope of a TAG_global_subroutine DIE. - - Don't attempt to add anonymous structures or unions since they have - no name. Anonymous enumerations however are processed, because we - want to extract their member names (the check for a tag name is - done later). - - Also, for variables and subroutines, check that this is the place - where the actual definition occurs, rather than just a reference - to an external. - */ - -static void -scan_partial_symbols (thisdie, enddie, objfile) - char *thisdie; - char *enddie; - struct objfile *objfile; -{ - char *nextdie; - char *temp; - struct dieinfo di; - - while (thisdie < enddie) - { - basicdieinfo (&di, thisdie, objfile); - if (di.die_length < SIZEOF_DIE_LENGTH) - { - break; - } - else - { - nextdie = thisdie + di.die_length; - /* To avoid getting complete die information for every die, we - only do it (below) for the cases we are interested in. */ - switch (di.die_tag) - { - case TAG_global_subroutine: - case TAG_subroutine: - completedieinfo (&di, objfile); - if (di.at_name && (di.has_at_low_pc || di.at_location)) - { - add_partial_symbol (&di, objfile); - /* If there is a sibling attribute, adjust the nextdie - pointer to skip the entire scope of the subroutine. - Apply some sanity checking to make sure we don't - overrun or underrun the range of remaining DIE's */ - if (di.at_sibling != 0) - { - temp = dbbase + di.at_sibling - dbroff; - if ((temp < thisdie) || (temp >= enddie)) - { - complain (&bad_die_ref, DIE_ID, DIE_NAME, - di.at_sibling); - } - else - { - nextdie = temp; - } - } - } - break; - case TAG_global_variable: - case TAG_local_variable: - completedieinfo (&di, objfile); - if (di.at_name && (di.has_at_low_pc || di.at_location)) - { - add_partial_symbol (&di, objfile); - } - break; - case TAG_typedef: - case TAG_class_type: - case TAG_structure_type: - case TAG_union_type: - completedieinfo (&di, objfile); - if (di.at_name) - { - add_partial_symbol (&di, objfile); - } - break; - case TAG_enumeration_type: - completedieinfo (&di, objfile); - if (di.at_name) - { - add_partial_symbol (&di, objfile); - } - add_enum_psymbol (&di, objfile); - break; - } - } - thisdie = nextdie; - } -} - -/* - -LOCAL FUNCTION - - scan_compilation_units -- build a psymtab entry for each compilation - -DESCRIPTION - - This is the top level dwarf parsing routine for building partial - symbol tables. - - It scans from the beginning of the DWARF table looking for the first - TAG_compile_unit DIE, and then follows the sibling chain to locate - each additional TAG_compile_unit DIE. - - For each TAG_compile_unit DIE it creates a partial symtab structure, - calls a subordinate routine to collect all the compilation unit's - global DIE's, file scope DIEs, typedef DIEs, etc, and then links the - new partial symtab structure into the partial symbol table. It also - records the appropriate information in the partial symbol table entry - to allow the chunk of DIE's and line number table for this compilation - unit to be located and re-read later, to generate a complete symbol - table entry for the compilation unit. - - Thus it effectively partitions up a chunk of DIE's for multiple - compilation units into smaller DIE chunks and line number tables, - and associates them with a partial symbol table entry. - -NOTES - - If any compilation unit has no line number table associated with - it for some reason (a missing at_stmt_list attribute, rather than - just one with a value of zero, which is valid) then we ensure that - the recorded file offset is zero so that the routine which later - reads line number table fragments knows that there is no fragment - to read. - -RETURNS - - Returns no value. - - */ - -static void -scan_compilation_units (thisdie, enddie, dbfoff, lnoffset, objfile) - char *thisdie; - char *enddie; - file_ptr dbfoff; - file_ptr lnoffset; - struct objfile *objfile; -{ - char *nextdie; - struct dieinfo di; - struct partial_symtab *pst; - int culength; - int curoff; - file_ptr curlnoffset; - - while (thisdie < enddie) - { - basicdieinfo (&di, thisdie, objfile); - if (di.die_length < SIZEOF_DIE_LENGTH) - { - break; - } - else if (di.die_tag != TAG_compile_unit) - { - nextdie = thisdie + di.die_length; - } - else - { - completedieinfo (&di, objfile); - set_cu_language (&di); - if (di.at_sibling != 0) - { - nextdie = dbbase + di.at_sibling - dbroff; - } - else - { - nextdie = thisdie + di.die_length; - } - curoff = thisdie - dbbase; - culength = nextdie - thisdie; - curlnoffset = di.has_at_stmt_list ? lnoffset + di.at_stmt_list : 0; - - /* First allocate a new partial symbol table structure */ - - pst = start_psymtab_common (objfile, base_section_offsets, - di.at_name, di.at_low_pc, - objfile -> global_psymbols.next, - objfile -> static_psymbols.next); - - pst -> texthigh = di.at_high_pc; - pst -> read_symtab_private = (char *) - obstack_alloc (&objfile -> psymbol_obstack, - sizeof (struct dwfinfo)); - DBFOFF (pst) = dbfoff; - DBROFF (pst) = curoff; - DBLENGTH (pst) = culength; - LNFOFF (pst) = curlnoffset; - pst -> read_symtab = dwarf_psymtab_to_symtab; - - /* Now look for partial symbols */ - - scan_partial_symbols (thisdie + di.die_length, nextdie, objfile); - - 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); - } - thisdie = nextdie; - } -} - -/* - -LOCAL FUNCTION - - new_symbol -- make a symbol table entry for a new symbol - -SYNOPSIS - - static struct symbol *new_symbol (struct dieinfo *dip, - struct objfile *objfile) - -DESCRIPTION - - 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. - */ - -static struct symbol * -new_symbol (dip, objfile) - struct dieinfo *dip; - struct objfile *objfile; -{ - struct symbol *sym = NULL; - - if (dip -> at_name != NULL) - { - sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack, - sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = create_name (dip -> at_name, - &objfile->symbol_obstack); - /* default assumptions */ - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_TYPE (sym) = decode_die_type (dip); - - /* 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 (dip -> die_tag) - { - case TAG_label: - SYMBOL_VALUE (sym) = dip -> at_low_pc; - SYMBOL_CLASS (sym) = LOC_LABEL; - break; - case TAG_global_subroutine: - case TAG_subroutine: - SYMBOL_VALUE (sym) = dip -> at_low_pc; - SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym)); - SYMBOL_CLASS (sym) = LOC_BLOCK; - if (dip -> die_tag == TAG_global_subroutine) - { - add_symbol_to_list (sym, &global_symbols); - } - else - { - add_symbol_to_list (sym, list_in_scope); - } - break; - case TAG_global_variable: - if (dip -> at_location != NULL) - { - SYMBOL_VALUE (sym) = locval (dip -> at_location); - add_symbol_to_list (sym, &global_symbols); - SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_VALUE (sym) += baseaddr; - } - break; - 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 (isreg) - { - SYMBOL_CLASS (sym) = LOC_REGISTER; - } - else if (offreg) - { - SYMBOL_CLASS (sym) = LOC_BASEREG; - SYMBOL_BASEREG (sym) = basereg; - } - else - { - SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_VALUE (sym) += baseaddr; - } - } - break; - case TAG_formal_parameter: - if (dip -> at_location != NULL) - { - SYMBOL_VALUE (sym) = locval (dip -> at_location); - } - add_symbol_to_list (sym, list_in_scope); - 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; - } - break; - case 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 TAG_class_type: - case TAG_structure_type: - case TAG_union_type: - case TAG_enumeration_type: - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; - add_symbol_to_list (sym, list_in_scope); - break; - case TAG_typedef: - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - 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. */ - break; - } - } - return (sym); -} - -/* - -LOCAL FUNCTION - - synthesize_typedef -- make a symbol table entry for a "fake" typedef - -SYNOPSIS - - static void synthesize_typedef (struct dieinfo *dip, - struct objfile *objfile, - struct type *type); - -DESCRIPTION - - Given a pointer to a DWARF information entry, synthesize a typedef - for the name in the DIE, using the specified type. - - This is used for C++ class, structs, unions, and enumerations to - set up the tag name as a type. - - */ - -static void -synthesize_typedef (dip, objfile, type) - struct dieinfo *dip; - struct objfile *objfile; - struct type *type; -{ - struct symbol *sym = NULL; - - if (dip -> at_name != NULL) - { - sym = (struct symbol *) - obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = create_name (dip -> at_name, - &objfile->symbol_obstack); - SYMBOL_INIT_LANGUAGE_SPECIFIC (sym, cu_language); - SYMBOL_TYPE (sym) = type; - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, list_in_scope); - } -} - -/* - -LOCAL FUNCTION - - decode_mod_fund_type -- decode a modified fundamental type - -SYNOPSIS - - static struct type *decode_mod_fund_type (char *typedata) - -DESCRIPTION - - Decode a block of data containing a modified fundamental - type specification. TYPEDATA is a pointer to the block, - which starts with a length containing the size of the rest - of the block. At the end of the block is a fundmental type - code value that gives the fundamental type. Everything - in between are type modifiers. - - We simply compute the number of modifiers and call the general - function decode_modified_type to do the actual work. -*/ - -static struct type * -decode_mod_fund_type (typedata) - char *typedata; -{ - struct type *typep = NULL; - unsigned short modcount; - int nbytes; - - /* Get the total size of the block, exclusive of the size itself */ - - nbytes = attribute_size (AT_mod_fund_type); - modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile); - typedata += nbytes; - - /* Deduct the size of the fundamental type bytes at the end of the block. */ - - modcount -= attribute_size (AT_fund_type); - - /* Now do the actual decoding */ - - typep = decode_modified_type (typedata, modcount, AT_mod_fund_type); - return (typep); -} - -/* - -LOCAL FUNCTION - - decode_mod_u_d_type -- decode a modified user defined type - -SYNOPSIS - - static struct type *decode_mod_u_d_type (char *typedata) - -DESCRIPTION - - Decode a block of data containing a modified user defined - type specification. TYPEDATA is a pointer to the block, - which consists of a two byte length, containing the size - of the rest of the block. At the end of the block is a - four byte value that gives a reference to a user defined type. - Everything in between are type modifiers. - - We simply compute the number of modifiers and call the general - function decode_modified_type to do the actual work. -*/ - -static struct type * -decode_mod_u_d_type (typedata) - char *typedata; -{ - struct type *typep = NULL; - unsigned short modcount; - int nbytes; - - /* Get the total size of the block, exclusive of the size itself */ - - nbytes = attribute_size (AT_mod_u_d_type); - modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile); - typedata += nbytes; - - /* Deduct the size of the reference type bytes at the end of the block. */ - - modcount -= attribute_size (AT_user_def_type); - - /* Now do the actual decoding */ - - typep = decode_modified_type (typedata, modcount, AT_mod_u_d_type); - return (typep); -} - -/* - -LOCAL FUNCTION - - decode_modified_type -- decode modified user or fundamental type - -SYNOPSIS - - static struct type *decode_modified_type (char *modifiers, - unsigned short modcount, int mtype) - -DESCRIPTION - - Decode a modified type, either a modified fundamental type or - a modified user defined type. MODIFIERS is a pointer to the - block of bytes that define MODCOUNT modifiers. Immediately - following the last modifier is a short containing the fundamental - type or a long containing the reference to the user defined - type. Which one is determined by MTYPE, which is either - AT_mod_fund_type or AT_mod_u_d_type to indicate what modified - type we are generating. - - We call ourself recursively to generate each modified type,` - until MODCOUNT reaches zero, at which point we have consumed - all the modifiers and generate either the fundamental type or - user defined type. When the recursion unwinds, each modifier - is applied in turn to generate the full modified type. - -NOTES - - If we find a modifier that we don't recognize, and it is not one - of those reserved for application specific use, then we issue a - warning and simply ignore the modifier. - -BUGS - - We currently ignore MOD_const and MOD_volatile. (FIXME) - - */ - -static struct type * -decode_modified_type (modifiers, modcount, mtype) - char *modifiers; - unsigned int modcount; - int mtype; -{ - struct type *typep = NULL; - unsigned short fundtype; - DIE_REF die_ref; - char modifier; - int nbytes; - - if (modcount == 0) - { - switch (mtype) - { - case AT_mod_fund_type: - nbytes = attribute_size (AT_fund_type); - fundtype = target_to_host (modifiers, nbytes, GET_UNSIGNED, - current_objfile); - typep = decode_fund_type (fundtype); - break; - case AT_mod_u_d_type: - nbytes = attribute_size (AT_user_def_type); - die_ref = target_to_host (modifiers, nbytes, GET_UNSIGNED, - current_objfile); - if ((typep = lookup_utype (die_ref)) == NULL) - { - typep = alloc_utype (die_ref, NULL); - } - break; - default: - complain (&botched_modified_type, DIE_ID, DIE_NAME, mtype); - typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); - break; - } - } - else - { - modifier = *modifiers++; - typep = decode_modified_type (modifiers, --modcount, mtype); - switch (modifier) - { - case MOD_pointer_to: - typep = lookup_pointer_type (typep); - break; - case MOD_reference_to: - typep = lookup_reference_type (typep); - break; - case MOD_const: - complain (&const_ignored, DIE_ID, DIE_NAME); /* FIXME */ - break; - case MOD_volatile: - complain (&volatile_ignored, DIE_ID, DIE_NAME); /* FIXME */ - break; - default: - if (!(MOD_lo_user <= (unsigned char) modifier - && (unsigned char) modifier <= MOD_hi_user)) - { - complain (&unknown_type_modifier, DIE_ID, DIE_NAME, modifier); - } - break; - } - } - return (typep); -} - -/* - -LOCAL FUNCTION - - decode_fund_type -- translate basic DWARF type to gdb base type - -DESCRIPTION - - Given an integer that is one of the fundamental DWARF types, - translate it to one of the basic internal gdb types and return - a pointer to the appropriate gdb type (a "struct type *"). - -NOTES - - For robustness, if we are asked to translate a fundamental - type that we are unprepared to deal with, we return int so - callers can always depend upon a valid type being returned, - and so gdb may at least do something reasonable by default. - If the type is not in the range of those types defined as - application specific types, we also issue a warning. -*/ - -static struct type * -decode_fund_type (fundtype) - unsigned int fundtype; -{ - struct type *typep = NULL; - - switch (fundtype) - { - - case FT_void: - typep = dwarf_fundamental_type (current_objfile, FT_VOID); - break; - - case FT_boolean: /* Was FT_set in AT&T version */ - typep = dwarf_fundamental_type (current_objfile, FT_BOOLEAN); - break; - - case FT_pointer: /* (void *) */ - typep = dwarf_fundamental_type (current_objfile, FT_VOID); - typep = lookup_pointer_type (typep); - break; - - case FT_char: - typep = dwarf_fundamental_type (current_objfile, FT_CHAR); - break; - - case FT_signed_char: - typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_CHAR); - break; - - case FT_unsigned_char: - typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_CHAR); - break; - - case FT_short: - typep = dwarf_fundamental_type (current_objfile, FT_SHORT); - break; - - case FT_signed_short: - typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_SHORT); - break; - - case FT_unsigned_short: - typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_SHORT); - break; - - case FT_integer: - typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); - break; - - case FT_signed_integer: - typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_INTEGER); - break; - - case FT_unsigned_integer: - typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER); - break; - - case FT_long: - typep = dwarf_fundamental_type (current_objfile, FT_LONG); - break; - - case FT_signed_long: - typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG); - break; - - case FT_unsigned_long: - typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG); - break; - - case FT_long_long: - typep = dwarf_fundamental_type (current_objfile, FT_LONG_LONG); - break; - - case FT_signed_long_long: - typep = dwarf_fundamental_type (current_objfile, FT_SIGNED_LONG_LONG); - break; - - case FT_unsigned_long_long: - typep = dwarf_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG); - break; - - case FT_float: - typep = dwarf_fundamental_type (current_objfile, FT_FLOAT); - break; - - case FT_dbl_prec_float: - typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT); - break; - - case FT_ext_prec_float: - typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT); - break; - - case FT_complex: - typep = dwarf_fundamental_type (current_objfile, FT_COMPLEX); - break; - - case FT_dbl_prec_complex: - typep = dwarf_fundamental_type (current_objfile, FT_DBL_PREC_COMPLEX); - break; - - case FT_ext_prec_complex: - typep = dwarf_fundamental_type (current_objfile, FT_EXT_PREC_COMPLEX); - break; - - } - - if (typep == NULL) - { - typep = dwarf_fundamental_type (current_objfile, FT_INTEGER); - if (!(FT_lo_user <= fundtype && fundtype <= FT_hi_user)) - { - complain (&unexpected_fund_type, DIE_ID, DIE_NAME, fundtype); - } - } - - return (typep); -} - -/* - -LOCAL FUNCTION - - create_name -- allocate a fresh copy of a string on an obstack - -DESCRIPTION - - Given a pointer to a string and a pointer to an obstack, allocates - a fresh copy of the string on the specified obstack. - -*/ - -static char * -create_name (name, obstackp) - char *name; - struct obstack *obstackp; -{ - int length; - char *newname; - - length = strlen (name) + 1; - newname = (char *) obstack_alloc (obstackp, length); - strcpy (newname, name); - return (newname); -} - -/* - -LOCAL FUNCTION - - basicdieinfo -- extract the minimal die info from raw die data - -SYNOPSIS - - void basicdieinfo (char *diep, struct dieinfo *dip, - struct objfile *objfile) - -DESCRIPTION - - Given a pointer to raw DIE data, and a pointer to an instance of a - die info structure, this function extracts the basic information - from the DIE data required to continue processing this DIE, along - with some bookkeeping information about the DIE. - - The information we absolutely must have includes the DIE tag, - and the DIE length. If we need the sibling reference, then we - will have to call completedieinfo() to process all the remaining - DIE information. - - Note that since there is no guarantee that the data is properly - aligned in memory for the type of access required (indirection - through anything other than a char pointer), and there is no - guarantee that it is in the same byte order as the gdb host, - we call a function which deals with both alignment and byte - swapping issues. Possibly inefficient, but quite portable. - - We also take care of some other basic things at this point, such - as ensuring that the instance of the die info structure starts - out completely zero'd and that curdie is initialized for use - in error reporting if we have a problem with the current die. - -NOTES - - All DIE's must have at least a valid length, thus the minimum - DIE size is SIZEOF_DIE_LENGTH. In order to have a valid tag, the - DIE size must be at least SIZEOF_DIE_TAG larger, otherwise they - are forced to be TAG_padding DIES. - - Padding DIES must be at least SIZEOF_DIE_LENGTH in length, implying - that if a padding DIE is used for alignment and the amount needed is - less than SIZEOF_DIE_LENGTH, then the padding DIE has to be big - enough to align to the next alignment boundry. - - We do some basic sanity checking here, such as verifying that the - length of the die would not cause it to overrun the recorded end of - the buffer holding the DIE info. If we find a DIE that is either - too small or too large, we force it's length to zero which should - cause the caller to take appropriate action. - */ - -static void -basicdieinfo (dip, diep, objfile) - struct dieinfo *dip; - char *diep; - struct objfile *objfile; -{ - curdie = dip; - memset (dip, 0, sizeof (struct dieinfo)); - dip -> die = diep; - dip -> die_ref = dbroff + (diep - dbbase); - dip -> die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED, - objfile); - if ((dip -> die_length < SIZEOF_DIE_LENGTH) || - ((diep + dip -> die_length) > (dbbase + dbsize))) - { - complain (&malformed_die, DIE_ID, DIE_NAME, dip -> die_length); - dip -> die_length = 0; - } - else if (dip -> die_length < (SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG)) - { - dip -> die_tag = TAG_padding; - } - else - { - diep += SIZEOF_DIE_LENGTH; - dip -> die_tag = target_to_host (diep, SIZEOF_DIE_TAG, GET_UNSIGNED, - objfile); - } -} - -/* - -LOCAL FUNCTION - - completedieinfo -- finish reading the information for a given DIE - -SYNOPSIS - - void completedieinfo (struct dieinfo *dip, struct objfile *objfile) - -DESCRIPTION - - Given a pointer to an already partially initialized die info structure, - scan the raw DIE data and finish filling in the die info structure - from the various attributes found. - - Note that since there is no guarantee that the data is properly - aligned in memory for the type of access required (indirection - through anything other than a char pointer), and there is no - guarantee that it is in the same byte order as the gdb host, - we call a function which deals with both alignment and byte - swapping issues. Possibly inefficient, but quite portable. - -NOTES - - Each time we are called, we increment the diecount variable, which - keeps an approximate count of the number of dies processed for - each compilation unit. This information is presented to the user - if the info_verbose flag is set. - - */ - -static void -completedieinfo (dip, objfile) - struct dieinfo *dip; - struct objfile *objfile; -{ - char *diep; /* Current pointer into raw DIE data */ - char *end; /* Terminate DIE scan here */ - unsigned short attr; /* Current attribute being scanned */ - unsigned short form; /* Form of the attribute */ - int nbytes; /* Size of next field to read */ - - diecount++; - diep = dip -> die; - end = diep + dip -> die_length; - diep += SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG; - while (diep < end) - { - attr = target_to_host (diep, SIZEOF_ATTRIBUTE, GET_UNSIGNED, objfile); - diep += SIZEOF_ATTRIBUTE; - if ((nbytes = attribute_size (attr)) == -1) - { - complain (&unknown_attribute_length, DIE_ID, DIE_NAME); - diep = end; - continue; - } - switch (attr) - { - case AT_fund_type: - dip -> at_fund_type = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_ordering: - dip -> at_ordering = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_bit_offset: - dip -> at_bit_offset = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_sibling: - dip -> at_sibling = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_stmt_list: - dip -> at_stmt_list = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - dip -> has_at_stmt_list = 1; - break; - case AT_low_pc: - dip -> at_low_pc = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - dip -> at_low_pc += baseaddr; - dip -> has_at_low_pc = 1; - break; - case AT_high_pc: - dip -> at_high_pc = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - dip -> at_high_pc += baseaddr; - break; - case AT_language: - dip -> at_language = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_user_def_type: - dip -> at_user_def_type = target_to_host (diep, nbytes, - GET_UNSIGNED, objfile); - break; - case AT_byte_size: - dip -> at_byte_size = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - dip -> has_at_byte_size = 1; - break; - case AT_bit_size: - dip -> at_bit_size = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_member: - dip -> at_member = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_discr: - dip -> at_discr = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_location: - dip -> at_location = diep; - break; - case AT_mod_fund_type: - dip -> at_mod_fund_type = diep; - break; - case AT_subscr_data: - dip -> at_subscr_data = diep; - break; - case AT_mod_u_d_type: - dip -> at_mod_u_d_type = diep; - break; - case AT_element_list: - dip -> at_element_list = diep; - dip -> short_element_list = 0; - break; - case AT_short_element_list: - dip -> at_element_list = diep; - dip -> short_element_list = 1; - break; - case AT_discr_value: - dip -> at_discr_value = diep; - break; - case AT_string_length: - dip -> at_string_length = diep; - break; - case AT_name: - dip -> at_name = diep; - break; - case AT_comp_dir: - /* For now, ignore any "hostname:" portion, since gdb doesn't - know how to deal with it. (FIXME). */ - dip -> at_comp_dir = strrchr (diep, ':'); - if (dip -> at_comp_dir != NULL) - { - dip -> at_comp_dir++; - } - else - { - dip -> at_comp_dir = diep; - } - break; - case AT_producer: - dip -> at_producer = diep; - break; - case AT_start_scope: - dip -> at_start_scope = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_stride_size: - dip -> at_stride_size = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_src_info: - dip -> at_src_info = target_to_host (diep, nbytes, GET_UNSIGNED, - objfile); - break; - case AT_prototyped: - dip -> at_prototyped = diep; - break; - default: - /* Found an attribute that we are unprepared to handle. However - it is specifically one of the design goals of DWARF that - consumers should ignore unknown attributes. As long as the - form is one that we recognize (so we know how to skip it), - we can just ignore the unknown attribute. */ - break; - } - form = FORM_FROM_ATTR (attr); - switch (form) - { - case FORM_DATA2: - diep += 2; - break; - case FORM_DATA4: - case FORM_REF: - diep += 4; - break; - case FORM_DATA8: - diep += 8; - break; - case FORM_ADDR: - diep += TARGET_FT_POINTER_SIZE (objfile); - break; - case FORM_BLOCK2: - diep += 2 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile); - break; - case FORM_BLOCK4: - diep += 4 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile); - break; - case FORM_STRING: - diep += strlen (diep) + 1; - break; - default: - complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form); - diep = end; - break; - } - } -} - -/* - -LOCAL FUNCTION - - target_to_host -- swap in target data to host - -SYNOPSIS - - target_to_host (char *from, int nbytes, int signextend, - struct objfile *objfile) - -DESCRIPTION - - Given pointer to data in target format in FROM, a byte count for - the size of the data in NBYTES, a flag indicating whether or not - the data is signed in SIGNEXTEND, and a pointer to the current - objfile in OBJFILE, convert the data to host format and return - the converted value. - -NOTES - - FIXME: If we read data that is known to be signed, and expect to - use it as signed data, then we need to explicitly sign extend the - result until the bfd library is able to do this for us. - - */ - -static unsigned long -target_to_host (from, nbytes, signextend, objfile) - char *from; - int nbytes; - int signextend; /* FIXME: Unused */ - struct objfile *objfile; -{ - unsigned long rtnval; - - switch (nbytes) - { - case 8: - rtnval = bfd_get_64 (objfile -> obfd, (bfd_byte *) from); - break; - case 4: - rtnval = bfd_get_32 (objfile -> obfd, (bfd_byte *) from); - break; - case 2: - rtnval = bfd_get_16 (objfile -> obfd, (bfd_byte *) from); - break; - case 1: - rtnval = bfd_get_8 (objfile -> obfd, (bfd_byte *) from); - break; - default: - complain (&no_bfd_get_N, DIE_ID, DIE_NAME, nbytes); - rtnval = 0; - break; - } - return (rtnval); -} - -/* - -LOCAL FUNCTION - - attribute_size -- compute size of data for a DWARF attribute - -SYNOPSIS - - static int attribute_size (unsigned int attr) - -DESCRIPTION - - Given a DWARF attribute in ATTR, compute the size of the first - piece of data associated with this attribute and return that - size. - - Returns -1 for unrecognized attributes. - - */ - -static int -attribute_size (attr) - unsigned int attr; -{ - int nbytes; /* Size of next data for this attribute */ - unsigned short form; /* Form of the attribute */ - - form = FORM_FROM_ATTR (attr); - switch (form) - { - case FORM_STRING: /* A variable length field is next */ - nbytes = 0; - break; - case FORM_DATA2: /* Next 2 byte field is the data itself */ - case FORM_BLOCK2: /* Next 2 byte field is a block length */ - nbytes = 2; - break; - case FORM_DATA4: /* Next 4 byte field is the data itself */ - case FORM_BLOCK4: /* Next 4 byte field is a block length */ - case FORM_REF: /* Next 4 byte field is a DIE offset */ - nbytes = 4; - break; - case FORM_DATA8: /* Next 8 byte field is the data itself */ - nbytes = 8; - break; - case FORM_ADDR: /* Next field size is target sizeof(void *) */ - nbytes = TARGET_FT_POINTER_SIZE (objfile); - break; - default: - complain (&unknown_attribute_form, DIE_ID, DIE_NAME, form); - nbytes = -1; - break; - } - return (nbytes); -} diff --git a/gnu/usr.bin/gdb/gdb/elfread.c b/gnu/usr.bin/gdb/gdb/elfread.c deleted file mode 100644 index 47a3de1..0000000 --- a/gnu/usr.bin/gdb/gdb/elfread.c +++ /dev/null @@ -1,805 +0,0 @@ -/* Read ELF (Executable and Linking Format) object files for GDB. - Copyright 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Fred Fish at 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include "bfd.h" -#include -#include "libelf.h" -/*#include "elf/mips.h"*/ -#include "symtab.h" -#include "symfile.h" -#include "objfiles.h" -#include "buildsym.h" -#include "stabsread.h" -#include "gdb-stabs.h" -#include "complaints.h" -#include "demangle.h" - -/* The struct elfinfo is available only during ELF symbol table and - psymtab reading. It is destroyed at the complation of psymtab-reading. - It's local to elf_symfile_read. */ - -struct elfinfo { - file_ptr dboffset; /* Offset to dwarf debug section */ - unsigned int dbsize; /* Size of dwarf debug section */ - file_ptr lnoffset; /* Offset to dwarf line number section */ - unsigned int lnsize; /* Size of dwarf line number section */ - asection *stabsect; /* Section pointer for .stab section */ - asection *stabindexsect; /* Section pointer for .stab.index section */ - asection *mdebugsect; /* Section pointer for .mdebug section */ -}; - -/* Various things we might complain about... */ - -struct complaint section_info_complaint = - {"elf/stab section information %s without a preceding file symbol", 0, 0}; - -struct complaint section_info_dup_complaint = - {"duplicated elf/stab section information for %s", 0, 0}; - -struct complaint stab_info_mismatch_complaint = - {"elf/stab section information missing for %s", 0, 0}; - -struct complaint stab_info_questionable_complaint = - {"elf/stab section information questionable for %s", 0, 0}; - -static void -elf_symfile_init PARAMS ((struct objfile *)); - -static void -elf_new_init PARAMS ((struct objfile *)); - -static void -elf_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int)); - -static void -elf_symfile_finish PARAMS ((struct objfile *)); - -static void -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 void -record_minimal_symbol_and_info PARAMS ((char *, CORE_ADDR, - enum minimal_symbol_type, char *, - struct objfile *)); - -static void -elf_locate_sections PARAMS ((bfd *, asection *, void *)); - -/* We are called once per section from elf_symfile_read. We - need to examine each section we are passed, check to see - if it is something we are interested in processing, and - if so, stash away some access information for the section. - - For now we recognize the dwarf debug information sections and - line number sections from matching their section names. The - ELF definition is no real help here since it has no direct - knowledge of DWARF (by design, so any debugging format can be - used). - - We also recognize the ".stab" sections used by the Sun compilers - released with Solaris 2. - - FIXME: The section names should not be hardwired strings (what - should they be? I don't think most object file formats have enough - section flags to specify what kind of debug section it is - -kingdon). */ - -static void -elf_locate_sections (ignore_abfd, sectp, eip) - bfd *ignore_abfd; - asection *sectp; - PTR eip; -{ - register struct elfinfo *ei; - - ei = (struct elfinfo *) eip; - if (STREQ (sectp -> name, ".debug")) - { - ei -> dboffset = sectp -> filepos; - ei -> dbsize = bfd_get_section_size_before_reloc (sectp); - } - else if (STREQ (sectp -> name, ".line")) - { - ei -> lnoffset = sectp -> filepos; - ei -> lnsize = bfd_get_section_size_before_reloc (sectp); - } - else if (STREQ (sectp -> name, ".stab")) - { - ei -> stabsect = sectp; - } - else if (STREQ (sectp -> name, ".stab.index")) - { - ei -> stabindexsect = sectp; - } - else if (STREQ (sectp -> name, ".mdebug")) - { - ei -> mdebugsect = sectp; - } -} - -#if 0 /* Currently unused */ - -char * -elf_interpreter (abfd) - bfd *abfd; -{ - sec_ptr interp_sec; - unsigned size; - char *interp = NULL; - - interp_sec = bfd_get_section_by_name (abfd, ".interp"); - if (interp_sec) - { - size = bfd_section_size (abfd, interp_sec); - interp = alloca (size); - if (bfd_get_section_contents (abfd, interp_sec, interp, (file_ptr)0, - size)) - { - interp = savestring (interp, size - 1); - } - else - { - interp = NULL; - } - } - return (interp); -} - -#endif - -static void -record_minimal_symbol_and_info (name, address, ms_type, info, objfile) - char *name; - CORE_ADDR address; - enum minimal_symbol_type ms_type; - char *info; /* FIXME, is this really char *? */ - struct objfile *objfile; -{ - int section; - - /* Guess the section from the type. This is likely to be wrong in - some cases. */ - switch (ms_type) - { - case mst_text: - case mst_file_text: - section = SECT_OFF_TEXT; -#ifdef SMASH_TEXT_ADDRESS - SMASH_TEXT_ADDRESS (address); -#endif - break; - case mst_data: - case mst_file_data: - section = SECT_OFF_DATA; - break; - case mst_bss: - case mst_file_bss: - section = SECT_OFF_BSS; - break; - default: - section = -1; - break; - } - - name = obsavestring (name, strlen (name), &objfile -> symbol_obstack); - prim_record_minimal_symbol_and_info (name, address, ms_type, info, section, - objfile); -} - -/* - -LOCAL FUNCTION - - elf_symtab_read -- read the symbol table of an ELF file - -SYNOPSIS - - void elf_symtab_read (bfd *abfd, CORE_ADDR addr, - struct objfile *objfile) - -DESCRIPTION - - Given an open bfd, a base address to relocate symbols to, and a - flag that specifies whether or not this bfd is for an executable - or not (may be shared library for example), add all the global - function and data symbols to the minimal symbol table. - - In stabs-in-ELF, as implemented by Sun, there are some local symbols - defined in the ELF symbol table, which can be used to locate - the beginnings of sections from each ".o" file that was linked to - form the executable objfile. We gather any such info and record it - in data structures hung off the objfile's private data. - -*/ - -static void -elf_symtab_read (abfd, addr, objfile, dynamic) - bfd *abfd; - CORE_ADDR addr; - struct objfile *objfile; - int dynamic; -{ - long storage_needed; - asymbol *sym; - asymbol **symbol_table; - long number_of_symbols; - long i; - int index; - struct cleanup *back_to; - CORE_ADDR symaddr; - enum minimal_symbol_type ms_type; - /* If sectinfo is nonNULL, it contains section info that should end up - filed in the objfile. */ - struct stab_section_info *sectinfo = NULL; - /* If filesym is nonzero, it points to a file symbol, but we haven't - seen any section info for it yet. */ - asymbol *filesym = 0; - struct dbx_symfile_info *dbx = (struct dbx_symfile_info *) - objfile->sym_stab_info; - unsigned long size; - int stripped = (bfd_get_symcount (abfd) == 0); - - if (dynamic) - { - storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd); - - /* Nothing to be done if there is no dynamic symtab. */ - if (storage_needed < 0) - return; - } - else - { - storage_needed = bfd_get_symtab_upper_bound (abfd); - if (storage_needed < 0) - error ("Can't read symbols from %s: %s", bfd_get_filename (abfd), - bfd_errmsg (bfd_get_error ())); - } - if (storage_needed > 0) - { - symbol_table = (asymbol **) xmalloc (storage_needed); - back_to = make_cleanup (free, symbol_table); - if (dynamic) - number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, - symbol_table); - else - number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); - if (number_of_symbols < 0) - error ("Can't read symbols from %s: %s", bfd_get_filename (abfd), - bfd_errmsg (bfd_get_error ())); - for (i = 0; i < number_of_symbols; i++) - { - sym = symbol_table[i]; - if (sym -> name == NULL || *sym -> name == '\0') - { - /* Skip names that don't exist (shouldn't happen), or names - that are null strings (may happen). */ - continue; - } - - /* If it is a nonstripped executable, do not enter dynamic - symbols, as the dynamic symbol table is usually a subset - of the main symbol table. - On Irix 5 however, the symbols for the procedure linkage - table entries have meaningful values only in the dynamic - symbol table, so we always examine undefined symbols. */ - if (dynamic && !stripped && sym -> section != &bfd_und_section) - continue; - if (sym -> flags & BSF_FILE) - { - /* STT_FILE debugging symbol that helps stabs-in-elf debugging. - Chain any old one onto the objfile; remember new sym. */ - if (sectinfo != NULL) - { - sectinfo -> next = dbx -> stab_section_info; - dbx -> stab_section_info = sectinfo; - sectinfo = NULL; - } - filesym = sym; - } - else if (sym -> flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK)) - { - /* Select global/local/weak symbols. Note that bfd puts abs - symbols in their own section, so all symbols we are - interested in will have a section. */ - /* Bfd symbols are section relative. */ - symaddr = sym -> value + sym -> section -> vma; - /* Relocate all non-absolute symbols by base address. */ - if (sym -> section != &bfd_abs_section) - { - symaddr += addr; - } - /* For non-absolute symbols, use the type of the section - they are relative to, to intuit text/data. Bfd provides - no way of figuring this out for absolute symbols. */ - if (sym -> section == &bfd_und_section - && (sym -> flags & BSF_GLOBAL) - && (sym -> flags & BSF_FUNCTION)) - { - /* Symbol is a reference to a function defined in - a shared library. - If its value is non zero then it is usually the - absolute address of the corresponding entry in - the procedure linkage table. - If its value is zero then the dynamic linker has to - resolve the symbol. We are unable to find any - meaningful address for this symbol in the - executable file, so we skip it. - Irix 5 has a zero value for all shared library functions - in the main symbol table, but the dynamic symbol table - provides the right values. */ - ms_type = mst_solib_trampoline; - symaddr = sym -> value; - if (symaddr == 0) - continue; - symaddr += addr; - } - else if (sym -> section == &bfd_abs_section) - { - /* This is a hack to get the minimal symbol type - right for Irix 5, which has absolute adresses - with special section indices for dynamic symbols. */ - unsigned short shndx = - ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx; - - switch (shndx) - { -#if 0 - case SHN_MIPS_TEXT: - ms_type = mst_text; - break; - case SHN_MIPS_DATA: - ms_type = mst_data; - break; - case SHN_MIPS_ACOMMON: - ms_type = mst_bss; - break; -#endif - default: - ms_type = mst_abs; - } - } - else if (sym -> section -> flags & SEC_CODE) - { - if (sym -> flags & BSF_GLOBAL) - { - ms_type = mst_text; - } - else if ((sym->name[0] == '.' && sym->name[1] == 'L') - || ((sym -> flags & BSF_LOCAL) - && sym->name[0] == 'L' - && sym->name[1] == 'L')) - /* Looks like a compiler-generated label. Skip it. - The assembler should be skipping these (to keep - executables small), but apparently with gcc on the - delta m88k SVR4, it loses. So to have us check too - should be harmless (but I encourage people to fix this - in the assembler instead of adding checks here). */ - continue; - else - { - ms_type = mst_file_text; - } - } - else if (sym -> section -> flags & SEC_ALLOC) - { - if (sym -> flags & BSF_GLOBAL) - { - if (sym -> section -> flags & SEC_LOAD) - { - ms_type = mst_data; - } - else - { - ms_type = mst_bss; - } - } - else if (sym -> flags & BSF_LOCAL) - { - /* Named Local variable in a Data section. Check its - name for stabs-in-elf. The STREQ macro checks the - first character inline, so we only actually do a - strcmp function call on names that start with 'B' - or 'D' */ - index = SECT_OFF_MAX; - if (STREQ ("Bbss.bss", sym -> name)) - { - index = SECT_OFF_BSS; - } - else if (STREQ ("Ddata.data", sym -> name)) - { - index = SECT_OFF_DATA; - } - else if (STREQ ("Drodata.rodata", sym -> name)) - { - index = SECT_OFF_RODATA; - } - if (index != SECT_OFF_MAX) - { - /* Found a special local symbol. Allocate a - sectinfo, if needed, and fill it in. */ - if (sectinfo == NULL) - { - sectinfo = (struct stab_section_info *) - xmmalloc (objfile -> md, sizeof (*sectinfo)); - memset ((PTR) sectinfo, 0, sizeof (*sectinfo)); - if (filesym == NULL) - { - complain (§ion_info_complaint, - sym -> name); - } - else - { - sectinfo -> filename = - (char *) filesym -> name; - } - } - if (sectinfo -> sections[index] != 0) - { - complain (§ion_info_dup_complaint, - sectinfo -> filename); - } - /* Bfd symbols are section relative. */ - symaddr = sym -> value + sym -> section -> vma; - /* Relocate non-absolute symbols by base address. */ - if (sym -> section != &bfd_abs_section) - { - symaddr += addr; - } - sectinfo -> sections[index] = symaddr; - /* The special local symbols don't go in the - minimal symbol table, so ignore this one. */ - continue; - } - /* Not a special stabs-in-elf symbol, do regular - symbol processing. */ - if (sym -> section -> flags & SEC_LOAD) - { - ms_type = mst_file_data; - } - else - { - ms_type = mst_file_bss; - } - } - else - { - ms_type = mst_unknown; - } - } - else - { - /* FIXME: Solaris2 shared libraries include lots of - odd "absolute" and "undefined" symbols, that play - hob with actions like finding what function the PC - is in. Ignore them if they aren't text, data, or bss. */ - /* ms_type = mst_unknown; */ - continue; /* Skip this symbol. */ - } - /* Pass symbol size field in via BFD. FIXME!!! */ - size = ((elf_symbol_type *) sym) -> internal_elf_sym.st_size; - record_minimal_symbol_and_info ((char *) sym -> name, symaddr, - ms_type, (PTR) size, objfile); - } - } - do_cleanups (back_to); - } -} - -/* Scan and build partial symbols for a symbol file. - We have been initialized by a call to elf_symfile_init, which - currently does nothing. - - SECTION_OFFSETS is a set of offsets to apply to relocate the symbols - in each section. We simplify it down to a single offset for all - symbols. FIXME. - - MAINLINE is true if we are reading the main symbol - table (as opposed to a shared lib or dynamically loaded file). - - This function only does the minimum work necessary for letting the - user "name" things symbolically; it does not read the entire symtab. - Instead, it reads the external and static symbols and puts them in partial - symbol tables. When more extensive information is requested of a - file, the corresponding partial symbol table is mutated into a full - fledged symbol table by going back and reading the symbols - for real. - - We look for sections with specific names, to tell us what debug - format to look for: FIXME!!! - - dwarf_build_psymtabs() builds psymtabs for DWARF symbols; - elfstab_build_psymtabs() handles STABS symbols; - mdebug_build_psymtabs() handles ECOFF debugging information. - - Note that ELF files have a "minimal" symbol table, which looks a lot - like a COFF symbol table, but has only the minimal information necessary - for linking. We process this also, and use the information to - build gdb's minimal symbol table. This gives us some minimal debugging - capability even for files compiled without -g. */ - -static void -elf_symfile_read (objfile, section_offsets, mainline) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; -{ - bfd *abfd = objfile->obfd; - struct elfinfo ei; - struct cleanup *back_to; - CORE_ADDR offset; - - init_minimal_symbol_collection (); - back_to = make_cleanup (discard_minimal_symbols, 0); - - memset ((char *) &ei, 0, sizeof (ei)); - - /* Allocate struct to keep track of the symfile */ - objfile->sym_stab_info = (PTR) - 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); - - /* Process the normal ELF symbol table first. This may write some - chain of info into the dbx_symfile_info in objfile->sym_stab_info, - which can later be used by elfstab_offset_sections. */ - - /* FIXME, should take a section_offsets param, not just an offset. */ - offset = ANOFFSET (section_offsets, 0); - elf_symtab_read (abfd, offset, objfile, 0); - - /* Add the dynamic symbols. */ - - elf_symtab_read (abfd, offset, objfile, 1); - - /* Now process debugging information, which is contained in - special ELF sections. We first have to find them... */ - - bfd_map_over_sections (abfd, elf_locate_sections, (PTR) &ei); - if (ei.dboffset && ei.lnoffset) - { - /* DWARF sections */ - dwarf_build_psymtabs (objfile, - section_offsets, mainline, - ei.dboffset, ei.dbsize, - ei.lnoffset, ei.lnsize); - } - if (ei.stabsect) - { - asection *str_sect; - - /* Stab sections have an associated string table that looks like - a separate section. */ - str_sect = bfd_get_section_by_name (abfd, ".stabstr"); - - /* FIXME should probably warn about a stab section without a stabstr. */ - if (str_sect) - elfstab_build_psymtabs (objfile, - section_offsets, - mainline, - ei.stabsect->filepos, - bfd_section_size (abfd, ei.stabsect), - str_sect->filepos, - bfd_section_size (abfd, str_sect)); - } - if (ei.mdebugsect) - { - 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); - } - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); - - do_cleanups (back_to); -} - -/* This cleans up the objfile's sym_stab_info pointer, and the chain of - stab_section_info's, that might be dangling from it. */ - -static void -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 stab_section_info *ssi, *nssi; - - ssi = dbxinfo->stab_section_info; - while (ssi) - { - nssi = ssi->next; - mfree (objfile->md, ssi); - ssi = nssi; - } - - dbxinfo->stab_section_info = 0; /* Just say No mo info about this. */ -} - - -/* 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). - - We reinitialize buildsym, since we may be reading stabs from an ELF file. */ - -static void -elf_new_init (ignore) - struct objfile *ignore; -{ - stabsread_new_init (); - buildsym_new_init (); -} - -/* 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. */ - -static void -elf_symfile_finish (objfile) - struct objfile *objfile; -{ - if (objfile -> sym_stab_info != NULL) - { - mfree (objfile -> md, objfile -> sym_stab_info); - } -} - -/* ELF specific initialization routine for reading symbols. - - It is passed a pointer to a struct sym_fns which contains, among other - things, the BFD for the file whose symbols are being read, and a slot for - a pointer to "private data" which we can fill with goodies. - - For now at least, we have nothing in particular to do, so this function is - just a stub. */ - -static void -elf_symfile_init (ignore) - struct objfile *ignore; -{ -} - -/* 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. - offsets to static variables are relative to the start of the data - segment *for that module before linking*. This information is - painfully squirreled away in the ELF symbol table as local symbols - with wierd names. Go get 'em when needed. */ - -void -elfstab_offset_sections (objfile, pst) - struct objfile *objfile; - struct partial_symtab *pst; -{ - char *filename = pst->filename; - struct dbx_symfile_info *dbx = (struct dbx_symfile_info *) - objfile->sym_stab_info; - struct stab_section_info *maybe = dbx->stab_section_info; - struct stab_section_info *questionable = 0; - int i; - char *p; - - /* The ELF symbol info doesn't include path names, so strip the path - (if any) from the psymtab filename. */ - while (0 != (p = strchr (filename, '/'))) - filename = p+1; - - /* FIXME: This linear search could speed up significantly - if it was chained in the right order to match how we search it, - and if we unchained when we found a match. */ - for (; maybe; maybe = maybe->next) - { - if (filename[0] == maybe->filename[0] - && STREQ (filename, maybe->filename)) - { - /* We found a match. But there might be several source files - (from different directories) with the same name. */ - if (0 == maybe->found) - break; - questionable = maybe; /* Might use it later. */ - } - } - - if (maybe == 0 && questionable != 0) - { - complain (&stab_info_questionable_complaint, filename); - maybe = questionable; - } - - if (maybe) - { - /* Found it! Allocate a new psymtab struct, and fill it in. */ - maybe->found++; - pst->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile -> psymbol_obstack, - sizeof (struct section_offsets) + - sizeof (pst->section_offsets->offsets) * (SECT_OFF_MAX-1)); - - for (i = 0; i < SECT_OFF_MAX; i++) - ANOFFSET (pst->section_offsets, i) = maybe->sections[i]; - return; - } - - /* We were unable to find any offsets for this file. Complain. */ - if (dbx->stab_section_info) /* If there *is* any info, */ - complain (&stab_info_mismatch_complaint, filename); -} - -/* Register that we are able to handle ELF object file formats. */ - -static struct sym_fns elf_sym_fns = -{ - bfd_target_elf_flavour, - elf_new_init, /* sym_new_init: init anything gbl to entire symtab */ - 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 */ - NULL /* next: pointer to next struct sym_fns */ -}; - -void -_initialize_elfread () -{ - add_symtab_fns (&elf_sym_fns); -} diff --git a/gnu/usr.bin/gdb/gdb/environ.c b/gnu/usr.bin/gdb/gdb/environ.c deleted file mode 100644 index 5d7a640..0000000 --- a/gnu/usr.bin/gdb/gdb/environ.c +++ /dev/null @@ -1,194 +0,0 @@ -/* environ.c -- library for manipulating environments for GNU. - Copyright (C) 1986, 1989 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) > (b) ? (a) : (b)) - -#include "defs.h" -#include "environ.h" -#include -#include "gdbcore.h" - - -/* Return a new environment object. */ - -struct environ * -make_environ () -{ - register struct environ *e; - - e = (struct environ *) xmalloc (sizeof (struct environ)); - - e->allocated = 10; - e->vector = (char **) xmalloc ((e->allocated + 1) * sizeof (char *)); - e->vector[0] = 0; - return e; -} - -/* Free an environment and all the strings in it. */ - -void -free_environ (e) - register struct environ *e; -{ - register char **vector = e->vector; - - while (*vector) - free (*vector++); - - free (e); -} - -/* Copy the environment given to this process into E. - Also copies all the strings in it, so we can be sure - that all strings in these environments are safe to free. */ - -void -init_environ (e) - register struct environ *e; -{ - extern char **environ; - register int i; - - if (environ == NULL) - return; - - for (i = 0; environ[i]; i++) /*EMPTY*/; - - if (e->allocated < i) - { - e->allocated = max (i, e->allocated + 10); - e->vector = (char **) xrealloc ((char *)e->vector, - (e->allocated + 1) * sizeof (char *)); - } - - memcpy (e->vector, environ, (i + 1) * sizeof (char *)); - - while (--i >= 0) - { - register int len = strlen (e->vector[i]); - register char *new = (char *) xmalloc (len + 1); - memcpy (new, e->vector[i], len + 1); - e->vector[i] = new; - } -} - -/* Return the vector of environment E. - This is used to get something to pass to execve. */ - -char ** -environ_vector (e) - struct environ *e; -{ - return e->vector; -} - -/* Return the value in environment E of variable VAR. */ - -char * -get_in_environ (e, var) - const struct environ *e; - const char *var; -{ - register int len = strlen (var); - register char **vector = e->vector; - register char *s; - - for (; (s = *vector) != NULL; vector++) - if (STREQN (s, var, len) && s[len] == '=') - return &s[len + 1]; - - return 0; -} - -/* Store the value in E of VAR as VALUE. */ - -void -set_in_environ (e, var, value) - struct environ *e; - const char *var; - const char *value; -{ - register int i; - register int len = strlen (var); - register char **vector = e->vector; - register char *s; - - for (i = 0; (s = vector[i]) != NULL; i++) - if (STREQN (s, var, len) && s[len] == '=') - break; - - if (s == 0) - { - if (i == e->allocated) - { - e->allocated += 10; - vector = (char **) xrealloc ((char *)vector, - (e->allocated + 1) * sizeof (char *)); - e->vector = vector; - } - vector[i + 1] = 0; - } - else - free (s); - - s = (char *) xmalloc (len + strlen (value) + 2); - strcpy (s, var); - strcat (s, "="); - strcat (s, value); - vector[i] = s; - - /* This used to handle setting the PATH and GNUTARGET variables - specially. The latter has been replaced by "set gnutarget" - (which has worked since GDB 4.11). The former affects searching - the PATH to find SHELL, and searching the PATH to find the - argument of "symbol-file" or "exec-file". Maybe we should have - some kind of "set exec-path" for that. But in any event, having - "set env" affect anything besides the inferior is a bad idea. - What if we want to change the environment we pass to the program - without afecting GDB's behavior? */ - - return; -} - -/* Remove the setting for variable VAR from environment E. */ - -void -unset_in_environ (e, var) - struct environ *e; - char *var; -{ - register int len = strlen (var); - register char **vector = e->vector; - register char *s; - - for (; (s = *vector) != NULL; vector++) - { - if (STREQN (s, var, len) && s[len] == '=') - { - free (s); - /* Walk through the vector, shuffling args down by one, including - the NULL terminator. Can't use memcpy() here since the regions - overlap, and memmove() might not be available. */ - while ((vector[0] = vector[1]) != NULL) - { - vector++; - } - break; - } - } -} diff --git a/gnu/usr.bin/gdb/gdb/environ.h b/gnu/usr.bin/gdb/gdb/environ.h deleted file mode 100644 index 6c9fd03..0000000 --- a/gnu/usr.bin/gdb/gdb/environ.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Header for environment manipulation library. - Copyright 1989, 1992 Free Software Foundation. - -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 (ENVIRON_H) -#define ENVIRON_H 1 - -/* We manipulate environments represented as these structures. */ - -struct environ -{ - /* Number of usable slots allocated in VECTOR. - VECTOR always has one slot not counted here, - to hold the terminating zero. */ - int allocated; - /* A vector of slots, ALLOCATED + 1 of them. - The first few slots contain strings "VAR=VALUE" - and the next one contains zero. - Then come some unused slots. */ - char **vector; -}; - -extern struct environ * -make_environ PARAMS ((void)); - -extern void -free_environ PARAMS ((struct environ *)); - -extern void -init_environ PARAMS ((struct environ *)); - -extern char * -get_in_environ PARAMS ((const struct environ *, const char *)); - -extern void -set_in_environ PARAMS ((struct environ *, const char *, - const char *)); - -extern void -unset_in_environ PARAMS ((struct environ *, char *)); - -extern char ** -environ_vector PARAMS ((struct environ *)); - -#endif /* defined (ENVIRON_H) */ diff --git a/gnu/usr.bin/gdb/gdb/eval.c b/gnu/usr.bin/gdb/gdb/eval.c deleted file mode 100644 index cb956ac..0000000 --- a/gnu/usr.bin/gdb/gdb/eval.c +++ /dev/null @@ -1,1226 +0,0 @@ -/* Evaluate expressions for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include -#include "symtab.h" -#include "gdbtypes.h" -#include "value.h" -#include "expression.h" -#include "target.h" -#include "frame.h" -#include "demangle.h" -#include "language.h" /* For CAST_IS_CONVERSION */ - -/* Values of NOSIDE argument to eval_subexp. */ -enum noside -{ EVAL_NORMAL, - EVAL_SKIP, /* Only effect is to increment pos. */ - EVAL_AVOID_SIDE_EFFECTS /* Don't modify any variables or - call any functions. The value - returned will have the correct - type, and will have an - approximately correct lvalue - type (inaccuracy: anything that is - listed as being in a register in - the function in which it was - declared will be lval_register). */ -}; - -/* Prototypes for local functions. */ - -static value_ptr -evaluate_subexp_for_sizeof PARAMS ((struct expression *, int *)); - -static value_ptr -evaluate_subexp_with_coercion PARAMS ((struct expression *, int *, - enum noside)); - -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)); - - -/* Parse the string EXP as a C expression, evaluate it, - and return the result as a number. */ - -CORE_ADDR -parse_and_eval_address (exp) - char *exp; -{ - struct expression *expr = parse_expression (exp); - register CORE_ADDR addr; - register struct cleanup *old_chain = - make_cleanup (free_current_contents, &expr); - - addr = value_as_pointer (evaluate_expression (expr)); - do_cleanups (old_chain); - return addr; -} - -/* Like parse_and_eval_address but takes a pointer to a char * variable - and advanced that variable across the characters parsed. */ - -CORE_ADDR -parse_and_eval_address_1 (expptr) - char **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); - - addr = value_as_pointer (evaluate_expression (expr)); - do_cleanups (old_chain); - return addr; -} - -value_ptr -parse_and_eval (exp) - char *exp; -{ - struct expression *expr = parse_expression (exp); - register value_ptr val; - register struct cleanup *old_chain - = make_cleanup (free_current_contents, &expr); - - val = evaluate_expression (expr); - do_cleanups (old_chain); - return val; -} - -/* Parse up to a comma (or to a closeparen) - in the string EXPP as an expression, evaluate it, and return the value. - EXPP is advanced to point to the comma. */ - -value_ptr -parse_to_comma_and_eval (expp) - char **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); - - val = evaluate_expression (expr); - do_cleanups (old_chain); - return val; -} - -/* Evaluate an expression in internal prefix form - such as is constructed by parse.y. - - See expression.h for info on the format of an expression. */ - -value_ptr -evaluate_expression (exp) - struct expression *exp; -{ - int pc = 0; - return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_NORMAL); -} - -/* Evaluate an expression, avoiding all memory references - and getting a value whose type alone is correct. */ - -value_ptr -evaluate_type (exp) - struct expression *exp; -{ - int pc = 0; - return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS); -} - -static value_ptr -evaluate_subexp (expect_type, exp, pos, noside) - struct type *expect_type; - register struct expression *exp; - register int *pos; - enum noside noside; -{ - enum exp_opcode op; - int tem, tem2, tem3; - register int pc, pc2 = 0, oldpos; - register value_ptr arg1 = NULL, arg2 = NULL, arg3; - struct type *type; - int nargs; - value_ptr *argvec; - - pc = (*pos)++; - op = exp->elts[pc].opcode; - - switch (op) - { - case OP_SCOPE: - tem = longest_to_int (exp->elts[pc + 2].longconst); - (*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1); - arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type, - 0, - exp->elts[pc + 1].type, - &exp->elts[pc + 3].string, - expect_type); - if (arg1 == NULL) - error ("There is no field named %s", &exp->elts[pc + 3].string); - return arg1; - - case OP_LONG: - (*pos) += 3; - return value_from_longest (exp->elts[pc + 1].type, - exp->elts[pc + 2].longconst); - - case OP_DOUBLE: - (*pos) += 3; - return value_from_double (exp->elts[pc + 1].type, - exp->elts[pc + 2].doubleconst); - - case OP_VAR_VALUE: - (*pos) += 3; - if (noside == EVAL_SKIP) - goto nosideret; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - struct symbol * sym = exp->elts[pc + 2].symbol; - enum lval_type lv; - - switch (SYMBOL_CLASS (sym)) - { - case LOC_CONST: - case LOC_LABEL: - case LOC_CONST_BYTES: - lv = not_lval; - break; - - case LOC_REGISTER: - case LOC_REGPARM: - lv = lval_register; - break; - - default: - lv = lval_memory; - break; - } - - return value_zero (SYMBOL_TYPE (sym), lv); - } - else - return value_of_variable (exp->elts[pc + 2].symbol, - exp->elts[pc + 1].block); - - case OP_LAST: - (*pos) += 2; - return - 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)); - - case OP_BOOL: - (*pos) += 2; - return value_from_longest (builtin_type_chill_bool, - exp->elts[pc + 1].longconst); - - case OP_INTERNALVAR: - (*pos) += 2; - return value_of_internalvar (exp->elts[pc + 1].internalvar); - - case OP_STRING: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - if (noside == EVAL_SKIP) - goto nosideret; - return value_string (&exp->elts[pc + 2].string, tem); - - case OP_BITSTRING: - error ("support for OP_BITSTRING unimplemented"); - break; - - case OP_ARRAY: - (*pos) += 3; - tem2 = longest_to_int (exp->elts[pc + 1].longconst); - tem3 = longest_to_int (exp->elts[pc + 2].longconst); - nargs = tem3 - tem2 + 1; - argvec = (value_ptr *) alloca (sizeof (value_ptr) * nargs); - for (tem = 0; tem < nargs; tem++) - { - /* Ensure that array expressions are coerced into pointer objects. */ - argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); - } - if (noside == EVAL_SKIP) - goto nosideret; - return (value_array (tem2, tem3, argvec)); - break; - - case TERNOP_COND: - /* Skip third and second args to evaluate the first one. */ - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - if (value_logical_not (arg1)) - { - evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); - return evaluate_subexp (NULL_TYPE, exp, pos, noside); - } - else - { - arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); - return arg2; - } - - case OP_FUNCALL: - (*pos) += 2; - op = exp->elts[*pos].opcode; - if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) - { - int fnptr; - - nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1; - /* First, evaluate the structure into arg2 */ - pc2 = (*pos)++; - - if (noside == EVAL_SKIP) - goto nosideret; - - if (op == STRUCTOP_MEMBER) - { - arg2 = evaluate_subexp_for_address (exp, pos, noside); - } - else - { - arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - } - - /* If the function is a virtual function, then the - aggregate value (providing the structure) plays - its part by providing the vtable. Otherwise, - it is just along for the ride: call the function - directly. */ - - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - - fnptr = longest_to_int (value_as_long (arg1)); - - if (METHOD_PTR_IS_VIRTUAL(fnptr)) - { - int fnoffset = METHOD_PTR_TO_VOFFSET(fnptr); - struct type *basetype; - struct type *domain_type = - TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))); - int i, j; - basetype = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)); - if (domain_type != basetype) - arg2 = value_cast(lookup_pointer_type (domain_type), arg2); - basetype = TYPE_VPTR_BASETYPE (domain_type); - for (i = TYPE_NFN_FIELDS (basetype) - 1; i >= 0; i--) - { - struct fn_field *f = TYPE_FN_FIELDLIST1 (basetype, i); - /* If one is virtual, then all are virtual. */ - if (TYPE_FN_FIELD_VIRTUAL_P (f, 0)) - for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j) - if (TYPE_FN_FIELD_VOFFSET (f, j) == fnoffset) - { - value_ptr temp = value_ind (arg2); - arg1 = value_virtual_fn_field (&temp, f, j, domain_type, 0); - arg2 = value_addr (temp); - goto got_it; - } - } - if (i < 0) - error ("virtual function at index %d not found", fnoffset); - } - else - { - VALUE_TYPE (arg1) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))); - } - got_it: - - /* Now, say which argument to start evaluating from */ - tem = 2; - } - else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) - { - /* Hair for method invocations */ - int tem2; - - nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1; - /* First, evaluate the structure into arg2 */ - pc2 = (*pos)++; - tem2 = longest_to_int (exp->elts[pc2 + 1].longconst); - *pos += 3 + BYTES_TO_EXP_ELEM (tem2 + 1); - if (noside == EVAL_SKIP) - goto nosideret; - - if (op == STRUCTOP_STRUCT) - { - /* If v is a variable in a register, and the user types - v.method (), this will produce an error, because v has - no address. - - A possible way around this would be to allocate a - copy of the variable on the stack, copy in the - contents, call the function, and copy out the - contents. I.e. convert this from call by reference - to call by copy-return (or whatever it's called). - However, this does not work because it is not the - same: the method being called could stash a copy of - the address, and then future uses through that address - (after the method returns) would be expected to - use the variable itself, not some copy of it. */ - arg2 = evaluate_subexp_for_address (exp, pos, noside); - } - else - { - arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - } - /* Now, say which argument to start evaluating from */ - tem = 2; - } - else - { - nargs = longest_to_int (exp->elts[pc + 1].longconst); - tem = 0; - } - /* Allocate arg vector, including space for the function to be - called in argvec[0] and a terminating NULL */ - argvec = (value_ptr *) alloca (sizeof (value_ptr) * (nargs + 2)); - for (; tem <= nargs; tem++) - /* Ensure that array expressions are coerced into pointer objects. */ - argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); - - /* signal end of arglist */ - argvec[tem] = 0; - - if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) - { - 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; - - if (static_memfuncp) - { - argvec[1] = argvec[0]; - nargs--; - argvec++; - } - } - else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) - { - argvec[1] = arg2; - argvec[0] = arg1; - } - - if (noside == EVAL_SKIP) - goto nosideret; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - /* If the return type doesn't look like a function type, call an - error. This can happen if somebody tries to turn a variable into - a function call. This is here because people often want to - call, eg, strcmp, which gdb doesn't know is a function. If - gdb isn't asked for it's opinion (ie. through "whatis"), - it won't offer it. */ - - struct type *ftype = - TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0])); - - if (ftype) - return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]))); - else - error ("Expression of type other than \"Function returning ...\" used as function"); - } - return call_function_by_hand (argvec[0], nargs, argvec + 1); - - case STRUCTOP_STRUCT: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1), - &exp->elts[pc + 2].string, - 0), - lval_memory); - else - { - value_ptr temp = arg1; - return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string, - NULL, "structure"); - } - - case STRUCTOP_PTR: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1), - &exp->elts[pc + 2].string, - 0), - lval_memory); - else - { - value_ptr temp = arg1; - return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string, - NULL, "structure pointer"); - } - - case STRUCTOP_MEMBER: - arg1 = evaluate_subexp_for_address (exp, pos, noside); - 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); - if (noside == EVAL_SKIP) - goto nosideret; - if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR) - goto bad_pointer_to_member; - type = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)); - if (TYPE_CODE (type) == TYPE_CODE_METHOD) - error ("not implemented: pointer-to-method in pointer-to-member construct"); - if (TYPE_CODE (type) != TYPE_CODE_MEMBER) - goto bad_pointer_to_member; - /* Now, convert these values to an address. */ - 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)); - return value_ind (arg3); - bad_pointer_to_member: - error("non-pointer-to-member value used in pointer-to-member construct"); - - case BINOP_CONCAT: - arg1 = evaluate_subexp_with_coercion (exp, pos, noside); - arg2 = evaluate_subexp_with_coercion (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); - 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); - 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); - else - return value_assign (arg1, arg2); - - case BINOP_ASSIGN_MODIFY: - (*pos) += 2; - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) - 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); - else if (op == BINOP_ADD) - arg2 = value_add (arg1, arg2); - else if (op == BINOP_SUB) - arg2 = value_sub (arg1, arg2); - else - arg2 = value_binop (arg1, arg2, op); - return value_assign (arg1, arg2); - - case BINOP_ADD: - arg1 = evaluate_subexp_with_coercion (exp, pos, noside); - arg2 = evaluate_subexp_with_coercion (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); - else - return value_add (arg1, arg2); - - case BINOP_SUB: - arg1 = evaluate_subexp_with_coercion (exp, pos, noside); - arg2 = evaluate_subexp_with_coercion (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); - else - return value_sub (arg1, arg2); - - case BINOP_MUL: - case BINOP_DIV: - case BINOP_REM: - case BINOP_MOD: - case BINOP_LSH: - case BINOP_RSH: - case BINOP_BITWISE_AND: - case BINOP_BITWISE_IOR: - case BINOP_BITWISE_XOR: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - arg2 = evaluate_subexp (NULL_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); - else - if (noside == EVAL_AVOID_SIDE_EFFECTS - && (op == BINOP_DIV || op == BINOP_REM || op == BINOP_MOD)) - return value_zero (VALUE_TYPE (arg1), not_lval); - else - return value_binop (arg1, arg2, op); - - case BINOP_SUBSCRIPT: - arg1 = evaluate_subexp_with_coercion (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 (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); - else - return value_subscript (arg1, arg2); - - case BINOP_IN: - arg1 = evaluate_subexp_with_coercion (exp, pos, noside); - arg2 = evaluate_subexp_with_coercion (exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - return value_in (arg1, arg2); - - case MULTI_SUBSCRIPT: - (*pos) += 2; - nargs = longest_to_int (exp->elts[pc + 1].longconst); - arg1 = evaluate_subexp_with_coercion (exp, pos, noside); - while (nargs-- > 0) - { - arg2 = evaluate_subexp_with_coercion (exp, pos, noside); - /* FIXME: EVAL_SKIP handling may not be correct. */ - if (noside == EVAL_SKIP) - { - if (nargs > 0) - { - continue; - } - else - { - goto nosideret; - } - } - /* FIXME: EVAL_AVOID_SIDE_EFFECTS handling may not be correct. */ - 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 (VALUE_TYPE (arg1)); - if (type != NULL) - { - arg1 = value_zero (type, VALUE_LVAL (arg1)); - noside = EVAL_SKIP; - continue; - } - else - { - error ("cannot subscript something of type `%s'", - TYPE_NAME (VALUE_TYPE (arg1))); - } - } - - if (binop_user_defined_p (op, arg1, arg2)) - { - arg1 = value_x_binop (arg1, arg2, op, OP_NULL); - } - else - { - arg1 = value_subscript (arg1, arg2); - } - } - return (arg1); - - case BINOP_LOGICAL_AND: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - if (noside == EVAL_SKIP) - { - arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - goto nosideret; - } - - oldpos = *pos; - arg2 = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - *pos = oldpos; - - 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); - } - else - { - tem = value_logical_not (arg1); - arg2 = evaluate_subexp (NULL_TYPE, exp, pos, - (tem ? EVAL_SKIP : noside)); - return value_from_longest (builtin_type_int, - (LONGEST) (!tem && !value_logical_not (arg2))); - } - - case BINOP_LOGICAL_OR: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - if (noside == EVAL_SKIP) - { - arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - goto nosideret; - } - - oldpos = *pos; - arg2 = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - *pos = oldpos; - - 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); - } - else - { - tem = value_logical_not (arg1); - arg2 = evaluate_subexp (NULL_TYPE, exp, pos, - (!tem ? EVAL_SKIP : noside)); - return value_from_longest (builtin_type_int, - (LONGEST) (!tem || !value_logical_not (arg2))); - } - - case BINOP_EQUAL: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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); - } - else - { - tem = value_equal (arg1, arg2); - return value_from_longest (builtin_type_int, (LONGEST) tem); - } - - case BINOP_NOTEQUAL: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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); - } - else - { - tem = value_equal (arg1, arg2); - return value_from_longest (builtin_type_int, (LONGEST) ! tem); - } - - case BINOP_LESS: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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); - } - else - { - tem = value_less (arg1, arg2); - return value_from_longest (builtin_type_int, (LONGEST) tem); - } - - case BINOP_GTR: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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); - } - else - { - tem = value_less (arg2, arg1); - return value_from_longest (builtin_type_int, (LONGEST) tem); - } - - case BINOP_GEQ: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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); - } - else - { - tem = value_less (arg2, arg1) || value_equal (arg1, arg2); - return value_from_longest (builtin_type_int, (LONGEST) tem); - } - - case BINOP_LEQ: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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); - } - else - { - tem = value_less (arg1, arg2) || value_equal (arg1, arg2); - return value_from_longest (builtin_type_int, (LONGEST) tem); - } - - case BINOP_REPEAT: - arg1 = evaluate_subexp (NULL_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) - error ("Non-integral right operand for \"@\" operator."); - if (noside == EVAL_AVOID_SIDE_EFFECTS) - return allocate_repeat_value (VALUE_TYPE (arg1), - longest_to_int (value_as_long (arg2))); - else - return value_repeat (arg1, longest_to_int (value_as_long (arg2))); - - case BINOP_COMMA: - evaluate_subexp (NULL_TYPE, exp, pos, noside); - return evaluate_subexp (NULL_TYPE, exp, pos, noside); - - case UNOP_NEG: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - if (unop_user_defined_p (op, arg1)) - return value_x_unop (arg1, op); - else - return value_neg (arg1); - - case UNOP_COMPLEMENT: - /* C++: check for and handle destructor names. */ - op = exp->elts[*pos].opcode; - - arg1 = evaluate_subexp (NULL_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); - else - return value_complement (arg1); - - case UNOP_LOGICAL_NOT: - arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - if (unop_user_defined_p (op, arg1)) - return value_x_unop (arg1, op); - else - return value_from_longest (builtin_type_int, - (LONGEST) value_logical_not (arg1)); - - case UNOP_IND: - if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR) - expect_type = TYPE_TARGET_TYPE (expect_type); - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR - || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF - /* In C you can dereference an array to get the 1st elt. */ - || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_ARRAY - ) - return value_zero (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)), - lval_memory); - else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT) - /* GDB allows dereferencing an int. */ - return value_zero (builtin_type_int, lval_memory); - else - error ("Attempt to take contents of a non-pointer value."); - } - return value_ind (arg1); - - case UNOP_ADDR: - /* C++: check for and handle pointer to members. */ - - op = exp->elts[*pos].opcode; - - if (noside == EVAL_SKIP) - { - if (op == OP_SCOPE) - { - int temm = longest_to_int (exp->elts[pc+3].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (temm + 1); - } - else - evaluate_subexp (expect_type, exp, pos, EVAL_SKIP); - goto nosideret; - } - - return evaluate_subexp_for_address (exp, pos, noside); - - case UNOP_SIZEOF: - if (noside == EVAL_SKIP) - { - evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); - goto nosideret; - } - return evaluate_subexp_for_sizeof (exp, pos); - - case UNOP_CAST: - (*pos) += 2; - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - return value_cast (exp->elts[pc + 1].type, arg1); - - case UNOP_MEMVAL: - (*pos) += 2; - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - return value_zero (exp->elts[pc + 1].type, lval_memory); - else - return value_at_lazy (exp->elts[pc + 1].type, - value_as_pointer (arg1)); - - case UNOP_PREINCREMENT: - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) - return arg1; - else if (unop_user_defined_p (op, arg1)) - { - return value_x_unop (arg1, op); - } - else - { - arg2 = value_add (arg1, value_from_longest (builtin_type_char, - (LONGEST) 1)); - return value_assign (arg1, arg2); - } - - case UNOP_PREDECREMENT: - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) - return arg1; - else if (unop_user_defined_p (op, arg1)) - { - return value_x_unop (arg1, op); - } - else - { - arg2 = value_sub (arg1, value_from_longest (builtin_type_char, - (LONGEST) 1)); - return value_assign (arg1, arg2); - } - - case UNOP_POSTINCREMENT: - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) - return arg1; - else if (unop_user_defined_p (op, arg1)) - { - return value_x_unop (arg1, op); - } - else - { - arg2 = value_add (arg1, value_from_longest (builtin_type_char, - (LONGEST) 1)); - value_assign (arg1, arg2); - return arg1; - } - - case UNOP_POSTDECREMENT: - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) - return arg1; - else if (unop_user_defined_p (op, arg1)) - { - return value_x_unop (arg1, op); - } - else - { - arg2 = value_sub (arg1, value_from_longest (builtin_type_char, - (LONGEST) 1)); - value_assign (arg1, arg2); - return arg1; - } - - case OP_THIS: - (*pos) += 1; - return value_of_this (1); - - case OP_TYPE: - error ("Attempt to use a type name as an expression"); - - default: - /* Removing this case and compiling with gcc -Wall reveals that - a lot of cases are hitting this case. Some of these should - probably be removed from expression.h (e.g. do we need a BINOP_SCOPE - and an OP_SCOPE?); others are legitimate expressions which are - (apparently) not fully implemented. - - If there are any cases landing here which mean a user error, - then they should be separate cases, with more descriptive - error messages. */ - - error ("\ -GDB does not (yet) know how to evaluated that kind of expression"); - } - - nosideret: - return value_from_longest (builtin_type_long, (LONGEST) 1); -} - -/* Evaluate a subexpression of EXP, at index *POS, - and return the address of that subexpression. - Advance *POS over the subexpression. - If the subexpression isn't an lvalue, get an error. - NOSIDE may be EVAL_AVOID_SIDE_EFFECTS; - then only the type of the result need be correct. */ - -static value_ptr -evaluate_subexp_for_address (exp, pos, noside) - register struct expression *exp; - register int *pos; - enum noside noside; -{ - enum exp_opcode op; - register int pc; - struct symbol *var; - - pc = (*pos); - op = exp->elts[pc].opcode; - - switch (op) - { - case UNOP_IND: - (*pos)++; - return evaluate_subexp (NULL_TYPE, exp, pos, noside); - - case UNOP_MEMVAL: - (*pos) += 3; - return value_cast (lookup_pointer_type (exp->elts[pc + 1].type), - evaluate_subexp (NULL_TYPE, exp, pos, noside)); - - case OP_VAR_VALUE: - var = exp->elts[pc + 2].symbol; - - /* C++: The "address" of a reference should yield the address - * of the object pointed to. Let value_addr() deal with it. */ - if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF) - goto default_case; - - (*pos) += 4; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - struct type *type = - lookup_pointer_type (SYMBOL_TYPE (var)); - enum address_class sym_class = SYMBOL_CLASS (var); - - if (sym_class == LOC_CONST - || sym_class == LOC_CONST_BYTES - || sym_class == LOC_REGISTER - || sym_class == LOC_REGPARM) - error ("Attempt to take address of register or constant."); - - return - value_zero (type, not_lval); - } - else - return - locate_var_value - (var, - block_innermost_frame (exp->elts[pc + 1].block)); - - default: - default_case: - if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - value_ptr x = evaluate_subexp (NULL_TYPE, exp, pos, noside); - if (VALUE_LVAL (x) == lval_memory) - return value_zero (lookup_pointer_type (VALUE_TYPE (x)), - not_lval); - else - error ("Attempt to take address of non-lval"); - } - return value_addr (evaluate_subexp (NULL_TYPE, exp, pos, noside)); - } -} - -/* Evaluate like `evaluate_subexp' except coercing arrays to pointers. - When used in contexts where arrays will be coerced anyway, this is - equivalent to `evaluate_subexp' but much faster because it avoids - actually fetching array contents (perhaps obsolete now that we have - VALUE_LAZY). - - Note that we currently only do the coercion for C expressions, where - arrays are zero based and the coercion is correct. For other languages, - with nonzero based arrays, coercion loses. Use CAST_IS_CONVERSION - to decide if coercion is appropriate. - - */ - -static value_ptr -evaluate_subexp_with_coercion (exp, pos, noside) - register struct expression *exp; - register int *pos; - enum noside noside; -{ - register enum exp_opcode op; - register int pc; - register value_ptr val; - struct symbol *var; - - pc = (*pos); - op = exp->elts[pc].opcode; - - switch (op) - { - case OP_VAR_VALUE: - var = exp->elts[pc + 2].symbol; - if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY - && CAST_IS_CONVERSION) - { - (*pos) += 4; - val = - locate_var_value - (var, block_innermost_frame (exp->elts[pc + 1].block)); - return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (var))), - val); - } - /* FALLTHROUGH */ - - default: - return evaluate_subexp (NULL_TYPE, exp, pos, noside); - } -} - -/* Evaluate a subexpression of EXP, at index *POS, - and return a value for the size of that subexpression. - Advance *POS over the subexpression. */ - -static value_ptr -evaluate_subexp_for_sizeof (exp, pos) - register struct expression *exp; - register int *pos; -{ - enum exp_opcode op; - register int pc; - value_ptr val; - - pc = (*pos); - op = exp->elts[pc].opcode; - - switch (op) - { - /* This case is handled specially - so that we avoid creating a value for the result type. - If the result type is very big, it's desirable not to - create a value unnecessarily. */ - case UNOP_IND: - (*pos)++; - val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - return value_from_longest (builtin_type_int, (LONGEST) - TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (val)))); - - case UNOP_MEMVAL: - (*pos) += 3; - return value_from_longest (builtin_type_int, - (LONGEST) TYPE_LENGTH (exp->elts[pc + 1].type)); - - case OP_VAR_VALUE: - (*pos) += 4; - return - value_from_longest - (builtin_type_int, - (LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 2].symbol))); - - default: - val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - return value_from_longest (builtin_type_int, - (LONGEST) TYPE_LENGTH (VALUE_TYPE (val))); - } -} - -/* Parse a type expression in the string [P..P+LENGTH). */ - -struct type * -parse_and_eval_type (p, length) - char *p; - int length; -{ - char *tmp = (char *)alloca (length + 4); - struct expression *expr; - tmp[0] = '('; - memcpy (tmp+1, p, length); - tmp[length+1] = ')'; - tmp[length+2] = '0'; - tmp[length+3] = '\0'; - expr = parse_expression (tmp); - if (expr->elts[0].opcode != UNOP_CAST) - error ("Internal error in eval_type."); - return expr->elts[1].type; -} diff --git a/gnu/usr.bin/gdb/gdb/exec.c b/gnu/usr.bin/gdb/gdb/exec.c deleted file mode 100644 index 4da0a48..0000000 --- a/gnu/usr.bin/gdb/gdb/exec.c +++ /dev/null @@ -1,506 +0,0 @@ -/* Work with executable files, for GDB. - Copyright 1988, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "gdbcmd.h" -#include "language.h" - -#ifdef USG -#include -#endif - -#include -#include -#include - -#include "gdbcore.h" - -#include -#include -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -/* Prototypes for local functions */ - -static void -add_to_section_table PARAMS ((bfd *, sec_ptr, PTR)); - -static void -exec_close PARAMS ((int)); - -static void -file_command PARAMS ((char *, int)); - -static void -set_section_command PARAMS ((char *, int)); - -static void -exec_files_info PARAMS ((struct target_ops *)); - -extern int info_verbose; - -/* The Binary File Descriptor handle for the executable file. */ - -bfd *exec_bfd = NULL; - -/* Whether to open exec and core files read-only or read-write. */ - -int write_files = 0; - -/* Text start and end addresses (KLUDGE) if needed */ - -#ifdef NEED_TEXT_START_END -CORE_ADDR text_start = 0; -CORE_ADDR text_end = 0; -#endif - -/* Forward decl */ - -extern struct target_ops exec_ops; - -/* ARGSUSED */ -static void -exec_close (quitting) - int quitting; -{ - if (exec_bfd) { - char *name = bfd_get_filename (exec_bfd); - bfd_close (exec_bfd); - free (name); - exec_bfd = NULL; - } - if (exec_ops.to_sections) { - free ((PTR)exec_ops.to_sections); - exec_ops.to_sections = NULL; - exec_ops.to_sections_end = NULL; - } -} - -/* 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); - - /* Remove any previous exec file. */ - unpush_target (&exec_ops); - - /* Now open and digest the file the user requested, if any. */ - - if (args) - { - char *scratch_pathname; - int scratch_chan; - - /* Scan through the args and pick up the first non option arg - as the filename. */ - - if ((argv = buildargv (args)) == NULL) - { - nomem (0); - } - make_cleanup (freeargv, (char *) argv); - - for (; (*argv != NULL) && (**argv == '-'); argv++) {;} - if (*argv == NULL) - { - error ("no exec file name was specified"); - } - - filename = tilde_expand (*argv); - make_cleanup (free, filename); - - scratch_chan = openp (getenv ("PATH"), 1, filename, - write_files? O_RDWR|O_BINARY: O_RDONLY|O_BINARY, 0, - &scratch_pathname); - if (scratch_chan < 0) - perror_with_name (filename); - - exec_bfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan); - if (!exec_bfd) - error ("Could not open `%s' as an executable file: %s", - scratch_pathname, bfd_errmsg (bfd_get_error ())); - if (!bfd_check_format (exec_bfd, bfd_object)) - { - /* Make sure to close exec_bfd, or else "run" might try to use - it. */ - exec_close (0); - error ("\"%s\": not in executable format: %s.", - scratch_pathname, bfd_errmsg (bfd_get_error ())); - } - - if (build_section_table (exec_bfd, &exec_ops.to_sections, - &exec_ops.to_sections_end)) - { - /* Make sure to close exec_bfd, or else "run" might try to use - it. */ - exec_close (0); - error ("Can't find the file sections in `%s': %s", - exec_bfd->filename, 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. */ - - 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 - - validate_files (); - - push_target (&exec_ops); - - /* Tell display code (if any) about the changed file name. */ - if (exec_file_display_hook) - (*exec_file_display_hook) (filename); - } - else if (from_tty) - printf_unfiltered ("No exec file now.\n"); -} - -/* Set both the exec file and the symbol file, in one command. - What a novelty. Why did GDB go through four major releases before this - command was added? */ - -static void -file_command (arg, from_tty) - char *arg; - int from_tty; -{ - /* FIXME, if we lose on reading the symbol file, we should revert - the exec file, but that's rough. */ - exec_file_command (arg, from_tty); - symbol_file_command (arg, from_tty); -} - - -/* Locate all mappable sections of a BFD file. - table_pp_char is a char * to get it through bfd_map_over_sections; - we cast it back to its proper type. */ - -static void -add_to_section_table (abfd, asect, table_pp_char) - bfd *abfd; - sec_ptr asect; - PTR table_pp_char; -{ - struct section_table **table_pp = (struct section_table **)table_pp_char; - flagword aflag; - - aflag = bfd_get_section_flags (abfd, asect); - if (!(aflag & SEC_ALLOC)) - return; - if (0 == bfd_section_size (abfd, asect)) - return; - (*table_pp)->bfd = abfd; - (*table_pp)->the_bfd_section = asect; - (*table_pp)->addr = bfd_section_vma (abfd, asect); - (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect); - (*table_pp)++; -} - -/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR. - Returns 0 if OK, 1 on error. */ - -int -build_section_table (some_bfd, start, end) - bfd *some_bfd; - struct section_table **start, **end; -{ - unsigned count; - - count = bfd_count_sections (some_bfd); - if (*start) - free ((PTR)*start); - *start = (struct section_table *) xmalloc (count * sizeof (**start)); - *end = *start; - bfd_map_over_sections (some_bfd, add_to_section_table, (char *)end); - if (*end > *start + count) - abort(); - /* We could realloc the table, but it probably loses for most files. */ - return 0; -} - -/* Read or write the exec file. - - Args are address within a BFD file, address within gdb address-space, - length, and a flag indicating whether to read or write. - - Result is a length: - - 0: We cannot handle this address and length. - > 0: We have handled N bytes starting at this address. - (If N == length, we did it all.) We might be able - to handle more bytes beyond this length, but no - promises. - < 0: We cannot handle this address, but if somebody - else handles (-N) bytes, we can start from there. - - The same routine is used to handle both core and exec files; - we just tail-call it with more arguments to select between them. */ - -int -xfer_memory (memaddr, myaddr, len, write, target) - CORE_ADDR memaddr; - char *myaddr; - int len; - int write; - struct target_ops *target; -{ - boolean res; - struct section_table *p; - CORE_ADDR nextsectaddr, memend; - boolean (*xfer_fn) PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); - - if (len <= 0) - abort(); - - memend = memaddr + len; - xfer_fn = write? bfd_set_section_contents: bfd_get_section_contents; - nextsectaddr = memend; - - for (p = target->to_sections; p < target->to_sections_end; p++) - { - if (p->addr <= memaddr) - if (p->endaddr >= memend) - { - /* 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) - { - /* This section ends before the transfer starts. */ - continue; - } - else - { - /* This section overlaps the transfer. Just do half. */ - len = p->endaddr - memaddr; - res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, memaddr - p->addr, len); - return (res != 0) ? len : 0; - } - else if (p->addr < nextsectaddr) - nextsectaddr = p->addr; - } - - if (nextsectaddr >= memend) - return 0; /* We can't help */ - else - return - (nextsectaddr - memaddr); /* Next boundary where we can help */ -} - -#ifdef FIXME -#ifdef REG_STACK_SEGMENT -/* MOVE TO BFD... */ - /* Pyramids and AM29000s have an extra segment in the virtual address space - for the (control) stack of register-window frames. The AM29000 folk - call it the "register stack" rather than the "memory stack". */ - else if (memaddr >= reg_stack_start && memaddr < reg_stack_end) - { - i = min (len, reg_stack_end - memaddr); - fileptr = memaddr - reg_stack_start + reg_stack_offset; - wanna_xfer = coredata; - } -#endif /* REG_STACK_SEGMENT */ -#endif /* FIXME */ - -void -print_section_info (t, abfd) - struct target_ops *t; - bfd *abfd; -{ - struct section_table *p; - - printf_filtered ("\t`%s', ", bfd_get_filename(abfd)); - wrap_here (" "); - printf_filtered ("file type %s.\n", bfd_get_target(abfd)); - if (abfd == exec_bfd) - { - printf_filtered ("\tEntry point: "); - print_address_numeric (bfd_get_start_address (abfd), 1, gdb_stdout); - printf_filtered ("\n"); - } - for (p = t->to_sections; p < t->to_sections_end; p++) - { - /* FIXME-32x64 need a print_address_numeric with field width */ - printf_filtered ("\t%s", local_hex_string_custom ((unsigned long) p->addr, "08l")); - printf_filtered (" - %s", local_hex_string_custom ((unsigned long) p->endaddr, "08l")); - if (info_verbose) - printf_filtered (" @ %s", - local_hex_string_custom ((unsigned long) p->the_bfd_section->filepos, "08l")); - printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section)); - if (p->bfd != abfd) - { - printf_filtered (" in %s", bfd_get_filename (p->bfd)); - } - printf_filtered ("\n"); - } -} - -static void -exec_files_info (t) - struct target_ops *t; -{ - print_section_info (t, exec_bfd); -} - -static void -set_section_command (args, from_tty) - char *args; - int from_tty; -{ - struct section_table *p; - char *secname; - unsigned seclen; - unsigned long secaddr; - char secprint[100]; - long offset; - - if (args == 0) - error ("Must specify section name and its virtual address"); - - /* Parse out section name */ - for (secname = args; !isspace(*args); args++) ; - seclen = args - secname; - - /* Parse out new virtual address */ - secaddr = parse_and_eval_address (args); - - for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++) { - if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen) - && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0') { - offset = secaddr - p->addr; - p->addr += offset; - p->endaddr += offset; - if (from_tty) - exec_files_info(&exec_ops); - return; - } - } - if (seclen >= sizeof (secprint)) - seclen = sizeof (secprint) - 1; - strncpy (secprint, secname, seclen); - secprint[seclen] = '\0'; - error ("Section %s not found", secprint); -} - -/* If mourn is being called in all the right places, this could be say - `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ - -static int -ignore (addr, contents) - CORE_ADDR addr; - char *contents; -{ - return 0; -} - -struct target_ops exec_ops = { - "exec", "Local exec file", - "Use an executable file as a target.\n\ -Specify the filename of the executable file.", - exec_file_command, exec_close, /* open, close */ - find_default_attach, 0, 0, 0, /* attach, detach, resume, wait, */ - 0, 0, /* fetch_registers, store_registers, */ - 0, /* prepare_to_store, */ - xfer_memory, exec_files_info, - ignore, ignore, /* insert_breakpoint, remove_breakpoint, */ - 0, 0, 0, 0, 0, /* terminal stuff */ - 0, 0, /* kill, load */ - 0, /* lookup sym */ - find_default_create_inferior, - 0, /* mourn_inferior */ - 0, /* can_run */ - 0, /* notice_signals */ - file_stratum, 0, /* next */ - 0, 1, 0, 0, 0, /* all mem, mem, stack, regs, exec */ - 0, 0, /* section pointers */ - OPS_MAGIC, /* Always the last thing */ -}; - -void -_initialize_exec() -{ - struct cmd_list_element *c; - - 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 = add_cmd ("exec-file", class_files, exec_file_command, - "Use FILE as program for getting contents of pure memory.\n\ -If FILE cannot be found as specified, your execution directory path\n\ -is searched for a command of that name.\n\ -No arg means have no executable file.", &cmdlist); - c->completer = filename_completer; - - add_com ("section", class_files, set_section_command, - "Change the base address of section SECTION of the exec file to ADDR.\n\ -This can be used if the exec file does not contain section addresses,\n\ -(such as in the a.out format), or when the addresses specified in the\n\ -file itself are wrong. Each section must be changed separately. The\n\ -``info files'' command lists all the sections and their addresses."); - - add_show_from_set - (add_set_cmd ("write", class_support, var_boolean, (char *)&write_files, - "Set writing into executable and core files.", - &setlist), - &showlist); - - add_target (&exec_ops); -} diff --git a/gnu/usr.bin/gdb/gdb/expprint.c b/gnu/usr.bin/gdb/gdb/expprint.c deleted file mode 100644 index 14e2a40..0000000 --- a/gnu/usr.bin/gdb/gdb/expprint.c +++ /dev/null @@ -1,624 +0,0 @@ -/* Print in infix form a struct expression. - Copyright (C) 1986, 1989, 1991 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 "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "value.h" -#include "language.h" -#include "parser-defs.h" - -/* Prototypes for local functions */ - -static void -print_subexp PARAMS ((struct expression *, int *, GDB_FILE *, enum precedence)); - -static void -print_simple_m2_func PARAMS ((char *, struct expression *, int *, GDB_FILE *)); - -void -print_expression (exp, stream) - struct expression *exp; - GDB_FILE *stream; -{ - int pc = 0; - print_subexp (exp, &pc, stream, PREC_NULL); -} - -/* Print the subexpression of EXP that starts in position POS, on STREAM. - PREC is the precedence of the surrounding operator; - if the precedence of the main operator of this subexpression is less, - parentheses are needed here. */ - -static void -print_subexp (exp, pos, stream, prec) - register struct expression *exp; - register int *pos; - GDB_FILE *stream; - enum precedence prec; -{ - register unsigned tem; - register const struct op_print *op_print_tab; - register int pc; - unsigned nargs; - register char *op_str; - int assign_modify = 0; - enum exp_opcode opcode; - enum precedence myprec = PREC_NULL; - /* Set to 1 for a right-associative operator. */ - int assoc = 0; - value_ptr val; - char *tempstr = NULL; - - op_print_tab = exp->language_defn->la_op_print_tab; - pc = (*pos)++; - opcode = exp->elts[pc].opcode; - switch (opcode) - { - /* Common ops */ - - case OP_SCOPE: - myprec = PREC_PREFIX; - assoc = 0; - fputs_filtered (type_name_no_tag (exp->elts[pc + 1].type), stream); - fputs_filtered ("::", stream); - nargs = longest_to_int (exp->elts[pc + 2].longconst); - (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1); - fputs_filtered (&exp->elts[pc + 3].string, stream); - return; - - case OP_LONG: - (*pos) += 3; - value_print (value_from_longest (exp->elts[pc + 1].type, - exp->elts[pc + 2].longconst), - stream, 0, Val_no_prettyprint); - return; - - case OP_DOUBLE: - (*pos) += 3; - value_print (value_from_double (exp->elts[pc + 1].type, - exp->elts[pc + 2].doubleconst), - stream, 0, Val_no_prettyprint); - return; - - case OP_VAR_VALUE: - { - struct block *b; - (*pos) += 3; - b = exp->elts[pc + 1].block; - if (b != NULL - && BLOCK_FUNCTION (b) != NULL - && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)) != NULL) - { - fputs_filtered (SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)), stream); - fputs_filtered ("::", stream); - } - fputs_filtered (SYMBOL_SOURCE_NAME (exp->elts[pc + 2].symbol), stream); - } - return; - - case OP_LAST: - (*pos) += 2; - fprintf_filtered (stream, "$%d", - longest_to_int (exp->elts[pc + 1].longconst)); - return; - - case OP_REGISTER: - (*pos) += 2; - fprintf_filtered (stream, "$%s", - reg_names[longest_to_int (exp->elts[pc + 1].longconst)]); - return; - - case OP_BOOL: - (*pos) += 2; - fprintf_filtered (stream, "%s", - longest_to_int (exp->elts[pc + 1].longconst) - ? "TRUE" : "FALSE"); - return; - - case OP_INTERNALVAR: - (*pos) += 2; - fprintf_filtered (stream, "$%s", - internalvar_name (exp->elts[pc + 1].internalvar)); - return; - - case OP_FUNCALL: - (*pos) += 2; - nargs = longest_to_int (exp->elts[pc + 1].longconst); - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered (" (", stream); - for (tem = 0; tem < nargs; tem++) - { - if (tem != 0) - fputs_filtered (", ", stream); - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - } - fputs_filtered (")", stream); - return; - - case OP_STRING: - nargs = longest_to_int (exp -> elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); - /* 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); - return; - - case OP_BITSTRING: - error ("support for OP_BITSTRING unimplemented"); - break; - - case OP_ARRAY: - (*pos) += 3; - nargs = longest_to_int (exp->elts[pc + 2].longconst); - nargs -= longest_to_int (exp->elts[pc + 1].longconst); - nargs++; - tem = 0; - if (exp->elts[pc + 4].opcode == OP_LONG - && exp->elts[pc + 5].type == builtin_type_char - && exp->language_defn->la_language == language_c) - { - /* Attempt to print C character arrays using string syntax. - Walk through the args, picking up one character from each - of the OP_LONG expression elements. If any array element - does not match our expection of what we should find for - a simple string, revert back to array printing. Note that - the last expression element is an explicit null terminator - byte, which doesn't get printed. */ - tempstr = alloca (nargs); - pc += 4; - while (tem < nargs) - { - if (exp->elts[pc].opcode != OP_LONG - || exp->elts[pc + 1].type != builtin_type_char) - { - /* Not a simple array of char, use regular array printing. */ - tem = 0; - break; - } - else - { - tempstr[tem++] = - longest_to_int (exp->elts[pc + 2].longconst); - pc += 4; - } - } - } - if (tem > 0) - { - LA_PRINT_STRING (stream, tempstr, nargs - 1, 0); - (*pos) = pc; - } - else - { - fputs_filtered (" {", stream); - for (tem = 0; tem < nargs; tem++) - { - if (tem != 0) - { - fputs_filtered (", ", stream); - } - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - } - fputs_filtered ("}", stream); - } - return; - - case TERNOP_COND: - if ((int) prec > (int) PREC_COMMA) - fputs_filtered ("(", stream); - /* Print the subexpressions, forcing parentheses - around any binary operations within them. - This is more parentheses than are strictly necessary, - but it looks clearer. */ - print_subexp (exp, pos, stream, PREC_HYPER); - fputs_filtered (" ? ", stream); - print_subexp (exp, pos, stream, PREC_HYPER); - fputs_filtered (" : ", stream); - print_subexp (exp, pos, stream, PREC_HYPER); - if ((int) prec > (int) PREC_COMMA) - fputs_filtered (")", stream); - return; - - case STRUCTOP_STRUCT: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered (".", stream); - fputs_filtered (&exp->elts[pc + 2].string, stream); - return; - - /* Will not occur for Modula-2 */ - case STRUCTOP_PTR: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("->", stream); - fputs_filtered (&exp->elts[pc + 2].string, stream); - return; - - case BINOP_SUBSCRIPT: - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("[", stream); - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - fputs_filtered ("]", stream); - return; - - case UNOP_POSTINCREMENT: - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("++", stream); - return; - - case UNOP_POSTDECREMENT: - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("--", stream); - return; - - case UNOP_CAST: - (*pos) += 2; - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered ("(", stream); - fputs_filtered ("(", stream); - type_print (exp->elts[pc + 1].type, "", stream, 0); - fputs_filtered (") ", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered (")", stream); - return; - - case UNOP_MEMVAL: - (*pos) += 2; - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered ("(", stream); - if (exp->elts[pc + 1].type->code == TYPE_CODE_FUNC && - exp->elts[pc + 3].opcode == OP_LONG) { - /* We have a minimal symbol fn, probably. It's encoded - as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address). - Swallow the OP_LONG (including both its opcodes); ignore - 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); - value_print (val, stream, 0, Val_no_prettyprint); - } else { - fputs_filtered ("{", stream); - type_print (exp->elts[pc + 1].type, "", stream, 0); - fputs_filtered ("} ", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - } - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered (")", stream); - return; - - case BINOP_ASSIGN_MODIFY: - opcode = exp->elts[pc + 1].opcode; - (*pos) += 2; - myprec = PREC_ASSIGN; - assoc = 1; - assign_modify = 1; - op_str = "???"; - for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) - if (op_print_tab[tem].opcode == opcode) - { - op_str = op_print_tab[tem].string; - break; - } - if (op_print_tab[tem].opcode != opcode) - /* Not found; don't try to keep going because we don't know how - to interpret further elements. */ - error ("Invalid expression"); - break; - - /* C++ ops */ - - case OP_THIS: - ++(*pos); - fputs_filtered ("this", stream); - return; - - /* Modula-2 ops */ - - case MULTI_SUBSCRIPT: - (*pos) += 2; - nargs = longest_to_int (exp->elts[pc + 1].longconst); - print_subexp (exp, pos, stream, PREC_SUFFIX); - fprintf_unfiltered (stream, " ["); - for (tem = 0; tem < nargs; tem++) - { - if (tem != 0) - fprintf_unfiltered (stream, ", "); - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - } - fprintf_unfiltered (stream, "]"); - return; - - case BINOP_VAL: - (*pos)+=2; - fprintf_unfiltered(stream,"VAL("); - type_print(exp->elts[pc+1].type,"",stream,0); - fprintf_unfiltered(stream,","); - print_subexp(exp,pos,stream,PREC_PREFIX); - fprintf_unfiltered(stream,")"); - return; - - case UNOP_CAP: - print_simple_m2_func("CAP",exp,pos,stream); - return; - - case UNOP_CHR: - print_simple_m2_func("CHR",exp,pos,stream); - return; - - case UNOP_ORD: - print_simple_m2_func("ORD",exp,pos,stream); - return; - - case UNOP_ABS: - print_simple_m2_func("ABS",exp,pos,stream); - return; - - case UNOP_FLOAT: - print_simple_m2_func("FLOAT",exp,pos,stream); - return; - - case UNOP_HIGH: - print_simple_m2_func("HIGH",exp,pos,stream); - return; - - case UNOP_MAX: - print_simple_m2_func("MAX",exp,pos,stream); - return; - - case UNOP_MIN: - print_simple_m2_func("MIN",exp,pos,stream); - return; - - case UNOP_ODD: - print_simple_m2_func("ODD",exp,pos,stream); - return; - - case UNOP_TRUNC: - print_simple_m2_func("TRUNC",exp,pos,stream); - return; - - case BINOP_INCL: - case BINOP_EXCL: - error("print_subexp: Not implemented."); - - /* Default ops */ - - default: - op_str = "???"; - for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) - if (op_print_tab[tem].opcode == opcode) - { - op_str = op_print_tab[tem].string; - myprec = op_print_tab[tem].precedence; - assoc = op_print_tab[tem].right_assoc; - break; - } - if (op_print_tab[tem].opcode != opcode) - /* Not found; don't try to keep going because we don't know how - to interpret further elements. For example, this happens - if opcode is OP_TYPE. */ - error ("Invalid expression"); - } - - if ((int) myprec < (int) prec) - fputs_filtered ("(", stream); - if ((int) opcode > (int) BINOP_END) - { - /* Unary prefix operator. */ - fputs_filtered (op_str, stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - } - else - { - /* Binary operator. */ - /* Print left operand. - If operator is right-associative, - increment precedence for this operand. */ - print_subexp (exp, pos, stream, - (enum precedence) ((int) myprec + assoc)); - /* Print the operator itself. */ - if (assign_modify) - fprintf_filtered (stream, " %s= ", op_str); - else if (op_str[0] == ',') - fprintf_filtered (stream, "%s ", op_str); - else - fprintf_filtered (stream, " %s ", op_str); - /* Print right operand. - If operator is left-associative, - increment precedence for this operand. */ - print_subexp (exp, pos, stream, - (enum precedence) ((int) myprec + !assoc)); - } - - if ((int) myprec < (int) prec) - fputs_filtered (")", stream); -} - -/* Print out something of the form (). - This is used to print out some builtin Modula-2 - functions. - FIXME: There is probably some way to get the precedence - rules to do this (print a unary operand with parens around it). */ -static void -print_simple_m2_func(s,exp,pos,stream) - char *s; - register struct expression *exp; - register int *pos; - GDB_FILE *stream; -{ - fprintf_unfiltered(stream,"%s(",s); - print_subexp(exp,pos,stream,PREC_PREFIX); - fprintf_unfiltered(stream,")"); -} - -/* Return the operator corresponding to opcode OP as - a string. NULL indicates that the opcode was not found in the - current language table. */ -char * -op_string(op) - enum exp_opcode op; -{ - int tem; - register const struct op_print *op_print_tab; - - op_print_tab = current_language->la_op_print_tab; - for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) - if (op_print_tab[tem].opcode == op) - return op_print_tab[tem].string; - return NULL; -} - -#ifdef DEBUG_EXPRESSIONS - -/* Support for dumping the raw data from expressions in a human readable - form. */ - -void -dump_expression (exp, stream, note) - struct expression *exp; - GDB_FILE *stream; - char *note; -{ - int elt; - char *opcode_name; - char *eltscan; - int eltsize; - - 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", - exp->language_defn->la_name, exp -> nelts, - sizeof (union exp_element)); - fprintf_filtered (stream, "\t%5s %20s %16s %s\n", "Index", "Opcode", - "Hex Value", "String Value"); - for (elt = 0; elt < exp -> nelts; elt++) - { - fprintf_filtered (stream, "\t%5d ", elt); - switch (exp -> elts[elt].opcode) - { - default: opcode_name = ""; 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_END: opcode_name = "BINOP_END"; break; - case TERNOP_COND: opcode_name = "TERNOP_COND"; 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_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; - } - fprintf_filtered (stream, "%20s ", opcode_name); - fprintf_filtered (stream, -#if defined (PRINTF_HAS_LONG_LONG) - "%ll16x ", -#else - "%l16x ", -#endif - exp -> elts[elt].longconst); - - for (eltscan = (char *) &exp->elts[elt], - eltsize = sizeof (union exp_element) ; - eltsize-- > 0; - eltscan++) - { - fprintf_filtered (stream, "%c", - isprint (*eltscan) ? (*eltscan & 0xFF) : '.'); - } - fprintf_filtered (stream, "\n"); - } -} - -#endif /* DEBUG_EXPRESSIONS */ diff --git a/gnu/usr.bin/gdb/gdb/expression.h b/gnu/usr.bin/gdb/gdb/expression.h deleted file mode 100644 index 1f85a3f..0000000 --- a/gnu/usr.bin/gdb/gdb/expression.h +++ /dev/null @@ -1,316 +0,0 @@ -/* Definitions for expressions stored in reversed prefix form, for GDB. - Copyright 1986, 1989, 1992 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 (EXPRESSION_H) -#define EXPRESSION_H 1 - -#ifdef __STDC__ -struct block; /* Forward declaration for prototypes */ -#endif - -/* Definitions for saved C expressions. */ - -/* An expression is represented as a vector of union exp_element's. - Each exp_element is an opcode, except that some opcodes cause - the following exp_element to be treated as a long or double constant - or as a variable. The opcodes are obeyed, using a stack for temporaries. - The value is left on the temporary stack at the end. */ - -/* When it is necessary to include a string, - it can occupy as many exp_elements as it needs. - We find the length of the string using strlen, - divide to find out how many exp_elements are used up, - and skip that many. Strings, like numbers, are indicated - by the preceding opcode. */ - -enum exp_opcode -{ - /* Used when it's necessary to pass an opcode which will be ignored, - or to catch uninitialized values. */ - OP_NULL, - -/* BINOP_... operate on two values computed by following subexpressions, - replacing them by one result value. They take no immediate arguments. */ - BINOP_ADD, /* + */ - BINOP_SUB, /* - */ - BINOP_MUL, /* * */ - BINOP_DIV, /* / */ - BINOP_REM, /* % */ - BINOP_MOD, /* mod (Knuth 1.2.4) */ - BINOP_LSH, /* << */ - BINOP_RSH, /* >> */ - BINOP_LOGICAL_AND, /* && */ - BINOP_LOGICAL_OR, /* || */ - BINOP_BITWISE_AND, /* & */ - BINOP_BITWISE_IOR, /* | */ - BINOP_BITWISE_XOR, /* ^ */ - BINOP_EQUAL, /* == */ - BINOP_NOTEQUAL, /* != */ - BINOP_LESS, /* < */ - BINOP_GTR, /* > */ - BINOP_LEQ, /* <= */ - BINOP_GEQ, /* >= */ - BINOP_REPEAT, /* @ */ - BINOP_ASSIGN, /* = */ - BINOP_COMMA, /* , */ - BINOP_SUBSCRIPT, /* x[y] */ - BINOP_EXP, /* Exponentiation */ - -/* C++. */ - BINOP_MIN, /* ? */ - BINOP_SCOPE, /* :: */ - - /* STRUCTOP_MEMBER is used for pointer-to-member constructs. - X . * Y translates into X STRUCTOP_MEMBER Y. */ - STRUCTOP_MEMBER, - /* STRUCTOP_MPTR is used for pointer-to-member constructs - when X is a pointer instead of an aggregate. */ - STRUCTOP_MPTR, -/* end of C++. */ - - /* For Modula-2 integer division DIV */ - BINOP_INTDIV, - - BINOP_ASSIGN_MODIFY, /* +=, -=, *=, and so on. - The following exp_element is another opcode, - a BINOP_, saying how to modify. - Then comes another BINOP_ASSIGN_MODIFY, - making three exp_elements in total. */ - - /* Modula-2 standard (binary) procedures*/ - BINOP_VAL, - BINOP_INCL, - BINOP_EXCL, - - /* Concatenate two operands, such as character strings or bitstrings. - If the first operand is a integer expression, then it means concatenate - the second operand with itself that many times. */ - BINOP_CONCAT, - - /* For Chill and Pascal. */ - BINOP_IN, /* Returns 1 iff ARG1 IN ARG2. */ - - /* This must be the highest BINOP_ value, for expprint.c. */ - BINOP_END, - -/* Operates on three values computed by following subexpressions. */ - TERNOP_COND, /* ?: */ - -/* Multidimensional subscript operator, such as Modula-2 x[a,b,...]. - The dimensionality is encoded in the operator, like the number of - function arguments in OP_FUNCALL, I.E. . - The value of the first following subexpression is subscripted - by each of the next following subexpressions, one per dimension. */ - - MULTI_SUBSCRIPT, - -/* The OP_... series take immediate following arguments. - After the arguments come another OP_... (the same one) - so that the grouping can be recognized from the end. */ - -/* OP_LONG is followed by a type pointer in the next exp_element - and the long constant value in the following exp_element. - Then comes another OP_LONG. - Thus, the operation occupies four exp_elements. */ - - OP_LONG, -/* OP_DOUBLE is similar but takes a double constant instead of a long one. */ - OP_DOUBLE, - - /* OP_VAR_VALUE takes one struct block * in the following element, - and one struct symbol * in the following exp_element, followed by - another OP_VAR_VALUE, making four exp_elements. If the block is - non-NULL, evaluate the symbol relative to the innermost frame - executing in that block; if the block is NULL use the selected frame. */ - - OP_VAR_VALUE, - -/* OP_LAST is followed by an integer in the next exp_element. - The integer is zero for the last value printed, - or it is the absolute number of a history element. - With another OP_LAST at the end, this makes three exp_elements. */ - OP_LAST, -/* OP_REGISTER is followed by an integer in the next exp_element. - This is the number of a register to fetch (as an int). - With another OP_REGISTER at the end, this makes three exp_elements. */ - OP_REGISTER, -/* OP_INTERNALVAR is followed by an internalvar ptr in the next exp_element. - With another OP_INTERNALVAR at the end, this makes three exp_elements. */ - OP_INTERNALVAR, -/* OP_FUNCALL is followed by an integer in the next exp_element. - The integer is the number of args to the function call. - That many plus one values from following subexpressions - are used, the first one being the function. - The integer is followed by a repeat of OP_FUNCALL, - making three exp_elements. */ - OP_FUNCALL, -/* OP_STRING represents a string constant. - Its format is the same as that of a STRUCTOP, but the string - data is just made into a string constant when the operation - is executed. */ - OP_STRING, -/* OP_BITSTRING represents a packed bitstring constant. - Its format is the same as that of a STRUCTOP, but the bitstring - data is just made into a bitstring constant when the operation - is executed. */ - OP_BITSTRING, -/* OP_ARRAY creates an array constant out of the following subexpressions. - It is followed by two exp_elements, the first containing an integer - that is the lower bound of the array and the second containing another - integer that is the upper bound of the array. The second integer is - followed by a repeat of OP_ARRAY, making four exp_elements total. - The bounds are used to compute the number of following subexpressions - to consume, as well as setting the bounds in the created array constant. - The type of the elements is taken from the type of the first subexp, - and they must all match. */ - OP_ARRAY, - -/* UNOP_CAST is followed by a type pointer in the next exp_element. - With another UNOP_CAST at the end, this makes three exp_elements. - It casts the value of the following subexpression. */ - UNOP_CAST, -/* UNOP_MEMVAL is followed by a type pointer in the next exp_element - With another UNOP_MEMVAL at the end, this makes three exp_elements. - It casts the contents of the word addressed by the value of the - following subexpression. */ - UNOP_MEMVAL, -/* UNOP_... operate on one value from a following subexpression - and replace it with a result. They take no immediate arguments. */ - UNOP_NEG, /* Unary - */ - UNOP_LOGICAL_NOT, /* Unary ! */ - UNOP_COMPLEMENT, /* Unary ~ */ - UNOP_IND, /* Unary * */ - UNOP_ADDR, /* Unary & */ - UNOP_PREINCREMENT, /* ++ before an expression */ - UNOP_POSTINCREMENT, /* ++ after an expression */ - UNOP_PREDECREMENT, /* -- before an expression */ - UNOP_POSTDECREMENT, /* -- after an expression */ - UNOP_SIZEOF, /* Unary sizeof (followed by expression) */ - - UNOP_PLUS, /* Unary plus */ - - UNOP_CAP, /* Modula-2 standard (unary) procedures */ - UNOP_CHR, - UNOP_ORD, - UNOP_ABS, - UNOP_FLOAT, - UNOP_HIGH, - UNOP_MAX, - UNOP_MIN, - UNOP_ODD, - UNOP_TRUNC, - - OP_BOOL, /* Modula-2 builtin BOOLEAN type */ - OP_M2_STRING, /* Modula-2 string constants */ - -/* STRUCTOP_... operate on a value from a following subexpression - by extracting a structure component specified by a string - that appears in the following exp_elements (as many as needed). - STRUCTOP_STRUCT is used for "." and STRUCTOP_PTR for "->". - They differ only in the error message given in case the value is - not suitable or the structure component specified is not found. - - The length of the string follows the opcode, followed by - BYTES_TO_EXP_ELEM(length) elements containing the data of the - string, followed by the length again and the opcode again. */ - - 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. */ - OP_THIS, - - /* OP_SCOPE surrounds a type name and a field name. The type - name is encoded as one element, but the field name stays as - a string, which, of course, is variable length. */ - OP_SCOPE, - - /* OP_TYPE is for parsing types, and used with the "ptype" command - so we can look up types that are qualified by scope, either with - the GDB "::" operator, or the Modula-2 '.' operator. */ - OP_TYPE -}; - -union exp_element -{ - enum exp_opcode opcode; - struct symbol *symbol; - LONGEST longconst; - double doubleconst; - /* Really sizeof (union exp_element) characters (or less for the last - element of a string). */ - char string; - struct type *type; - struct internalvar *internalvar; - struct block *block; -}; - -struct expression -{ - const struct language_defn *language_defn; /* language it was entered in */ - int nelts; - union exp_element elts[1]; -}; - -/* Macros for converting between number of expression elements and bytes - to store that many expression elements. */ - -#define EXP_ELEM_TO_BYTES(elements) \ - ((elements) * sizeof (union exp_element)) -#define BYTES_TO_EXP_ELEM(bytes) \ - (((bytes) + sizeof (union exp_element) - 1) / sizeof (union exp_element)) - -/* From parse.c */ - -extern struct expression * -parse_expression PARAMS ((char *)); - -extern struct expression * -parse_exp_1 PARAMS ((char **, struct block *, int)); - -/* The innermost context required by the stack and register variables - we've encountered so far. To use this, set it to NULL, then call - parse_, then look at it. */ -extern struct block *innermost_block; - -/* From expprint.c */ - -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 */ - -#endif /* !defined (EXPRESSION_H) */ diff --git a/gnu/usr.bin/gdb/gdb/findvar.c b/gnu/usr.bin/gdb/gdb/findvar.c deleted file mode 100644 index 59c813c..0000000 --- a/gnu/usr.bin/gdb/gdb/findvar.c +++ /dev/null @@ -1,1242 +0,0 @@ -/* Find a variable's value in memory, for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991 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 "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "frame.h" -#include "value.h" -#include "gdbcore.h" -#include "inferior.h" -#include "target.h" - -/* 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. */ - -#if TARGET_CHAR_BIT != 8 || HOST_CHAR_BIT != 8 - /* 8 bit characters are a pretty safe assumption these days, so we - assume it throughout all these swapping routines. If we had to deal with - 9 bit characters, we would need to make len be in bits and would have - to re-write these routines... */ - you lose -#endif - -LONGEST -extract_signed_integer (addr, len) - PTR addr; - int len; -{ - LONGEST retval; - unsigned char *p; - unsigned char *startaddr = (unsigned char *)addr; - unsigned char *endaddr = startaddr + len; - - if (len > sizeof (LONGEST)) - error ("\ -That operation is not available on integers of more than %d bytes.", - sizeof (LONGEST)); - - /* Start at the most significant end of the integer, and work towards - the least significant. */ -#if TARGET_BYTE_ORDER == BIG_ENDIAN - p = startaddr; -#else - p = endaddr - 1; -#endif - /* Do the sign extension once at the start. */ - retval = ((LONGEST)*p ^ 0x80) - 0x80; -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (++p; p < endaddr; ++p) -#else - for (--p; p >= startaddr; --p) -#endif - { - retval = (retval << 8) | *p; - } - return retval; -} - -unsigned LONGEST -extract_unsigned_integer (addr, len) - PTR addr; - int len; -{ - unsigned LONGEST retval; - unsigned char *p; - unsigned char *startaddr = (unsigned char *)addr; - unsigned char *endaddr = startaddr + len; - - if (len > sizeof (unsigned LONGEST)) - error ("\ -That operation is not available on integers of more than %d bytes.", - sizeof (unsigned LONGEST)); - - /* Start at the most significant end of the integer, and work towards - the least significant. */ - retval = 0; -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (p = startaddr; p < endaddr; ++p) -#else - for (p = endaddr - 1; p >= startaddr; --p) -#endif - { - retval = (retval << 8) | *p; - } - return retval; -} - -CORE_ADDR -extract_address (addr, len) - PTR addr; - int 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); -} - -void -store_signed_integer (addr, len, val) - PTR addr; - int len; - LONGEST val; -{ - unsigned char *p; - unsigned char *startaddr = (unsigned char *)addr; - unsigned char *endaddr = startaddr + len; - - /* Start at the least significant end of the integer, and work towards - the most significant. */ -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (p = endaddr - 1; p >= startaddr; --p) -#else - for (p = startaddr; p < endaddr; ++p) -#endif - { - *p = val & 0xff; - val >>= 8; - } -} - -void -store_unsigned_integer (addr, len, val) - PTR addr; - int len; - unsigned LONGEST val; -{ - unsigned char *p; - unsigned char *startaddr = (unsigned char *)addr; - unsigned char *endaddr = startaddr + len; - - /* Start at the least significant end of the integer, and work towards - the most significant. */ -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (p = endaddr - 1; p >= startaddr; --p) -#else - for (p = startaddr; p < endaddr; ++p) -#endif - { - *p = val & 0xff; - val >>= 8; - } -} - -void -store_address (addr, len, val) - PTR addr; - int len; - CORE_ADDR 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); -} - -/* Swap LEN bytes at BUFFER between target and host byte-order. This is - the wrong way to do byte-swapping because it assumes that you have a way - to have a host variable of exactly the right size. Once extract_floating - and store_floating have been fixed, this can go away. */ -#if TARGET_BYTE_ORDER == HOST_BYTE_ORDER -#define SWAP_TARGET_AND_HOST(buffer,len) -#else /* Target and host byte order differ. */ -#define SWAP_TARGET_AND_HOST(buffer,len) \ - { \ - char tmp; \ - char *p = (char *)(buffer); \ - char *q = ((char *)(buffer)) + len - 1; \ - for (; p < q; p++, q--) \ - { \ - tmp = *q; \ - *q = *p; \ - *p = tmp; \ - } \ - } -#endif /* Target and host byte order differ. */ - -/* There are many problems with floating point cross-debugging. - - 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. */ - -double -extract_floating (addr, len) - PTR addr; - int len; -{ - if (len == sizeof (float)) - { - float retval; - memcpy (&retval, addr, sizeof (retval)); - SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); - return retval; - } - else if (len == sizeof (double)) - { - double retval; - memcpy (&retval, addr, sizeof (retval)); - SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); - return retval; - } - else - { - error ("Can't deal with a floating point number of %d bytes.", len); - } -} - -void -store_floating (addr, len, val) - PTR addr; - int len; - double val; -{ - if (len == sizeof (float)) - { - float floatval = val; - SWAP_TARGET_AND_HOST (&floatval, sizeof (floatval)); - memcpy (addr, &floatval, sizeof (floatval)); - } - else if (len == sizeof (double)) - { - SWAP_TARGET_AND_HOST (&val, sizeof (val)); - memcpy (addr, &val, sizeof (val)); - } - else - { - error ("Can't deal with a floating point number of %d bytes.", len); - } -} - -#if !defined (GET_SAVED_REGISTER) - -/* Return the address in which frame FRAME's value of register REGNUM - has been saved in memory. Or return zero if it has not been saved. - If REGNUM specifies the SP, the value we return is actually - the SP value, not an address where it was saved. */ - -CORE_ADDR -find_saved_register (frame, regnum) - FRAME frame; - int regnum; -{ - struct frame_info *fi; - struct frame_saved_regs saved_regs; - - register FRAME frame1 = 0; - register CORE_ADDR addr = 0; - - if (frame == 0) /* No regs saved if want current frame */ - return 0; - -#ifdef HAVE_REGISTER_WINDOWS - /* We assume that a register in a register window will only be saved - in one place (since the name changes and/or disappears as you go - towards inner frames), so we only call get_frame_saved_regs on - the current frame. This is directly in contradiction to the - usage below, which assumes that registers used in a frame must be - saved in a lower (more interior) frame. This change is a result - of working on a register window machine; get_frame_saved_regs - always returns the registers saved within a frame, within the - context (register namespace) of that frame. */ - - /* However, note that we don't want this to return anything if - nothing is saved (if there's a frame inside of this one). Also, - callers to this routine asking for the stack pointer want the - stack pointer saved for *this* frame; this is returned from the - next frame. */ - - - if (REGISTER_IN_WINDOW_P(regnum)) - { - frame1 = get_next_frame (frame); - if (!frame1) return 0; /* Registers of this frame are - active. */ - - /* Get the SP from the next frame in; it will be this - current frame. */ - if (regnum != SP_REGNUM) - frame1 = frame; - - fi = get_frame_info (frame1); - get_frame_saved_regs (fi, &saved_regs); - return saved_regs.regs[regnum]; /* ... which might be zero */ - } -#endif /* HAVE_REGISTER_WINDOWS */ - - /* Note that this next routine assumes that registers used in - frame x will be saved only in the frame that x calls and - frames interior to it. This is not true on the sparc, but the - above macro takes care of it, so we should be all right. */ - while (1) - { - QUIT; - frame1 = get_prev_frame (frame1); - if (frame1 == 0 || frame1 == frame) - break; - fi = get_frame_info (frame1); - get_frame_saved_regs (fi, &saved_regs); - if (saved_regs.regs[regnum]) - addr = saved_regs.regs[regnum]; - } - - return addr; -} - -/* 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). 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). Set *ADDRP to the address, either in memory - on as a REGISTER_BYTE offset into the registers array. - - Note that this implementation never sets *LVAL to not_lval. But - it can be replaced by defining GET_SAVED_REGISTER and supplying - your own. - - The argument RAW_BUFFER must point to aligned memory. */ - -void -get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) - char *raw_buffer; - int *optimized; - CORE_ADDR *addrp; - FRAME frame; - int regnum; - enum lval_type *lval; -{ - CORE_ADDR addr; - /* Normal systems don't optimize out things with register numbers. */ - if (optimized != NULL) - *optimized = 0; - addr = find_saved_register (frame, regnum); - if (addr != 0) - { - if (lval != NULL) - *lval = lval_memory; - if (regnum == SP_REGNUM) - { - if (raw_buffer != NULL) - { - /* Put it back in target format. */ - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), addr); - } - if (addrp != NULL) - *addrp = 0; - return; - } - if (raw_buffer != NULL) - read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum)); - } - else - { - if (lval != NULL) - *lval = lval_register; - addr = REGISTER_BYTE (regnum); - if (raw_buffer != NULL) - read_register_gen (regnum, raw_buffer); - } - if (addrp != NULL) - *addrp = addr; -} -#endif /* GET_SAVED_REGISTER. */ - -/* 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; -{ - int optim; - if (regnum == FP_REGNUM && selected_frame) - { - /* Put it back in target format. */ - store_address (myaddr, REGISTER_RAW_SIZE(FP_REGNUM), - FRAME_FP(selected_frame)); - return 0; - } - - get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, selected_frame, - regnum, (enum lval_type *)NULL); - return optim; -} - -/* Return a `value' with the contents of register REGNUM - in its virtual format, with the type specified by - REGISTER_VIRTUAL_TYPE. */ - -value_ptr -value_of_register (regnum) - int regnum; -{ - CORE_ADDR addr; - int optim; - register value_ptr reg_val; - char raw_buffer[MAX_REGISTER_RAW_SIZE]; - enum lval_type lval; - - get_saved_register (raw_buffer, &optim, &addr, - selected_frame, regnum, &lval); - - reg_val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum)); - - /* Convert raw data to virtual format if necessary. */ - -#ifdef REGISTER_CONVERTIBLE - if (REGISTER_CONVERTIBLE (regnum)) - { - REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum), - raw_buffer, VALUE_CONTENTS_RAW (reg_val)); - } - else -#endif - memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer, - REGISTER_RAW_SIZE (regnum)); - VALUE_LVAL (reg_val) = lval; - VALUE_ADDRESS (reg_val) = addr; - VALUE_REGNO (reg_val) = regnum; - VALUE_OPTIMIZED_OUT (reg_val) = optim; - return reg_val; -} - -/* Low level examining and depositing of registers. - - The caller is responsible for making - sure that the inferior is stopped before calling the fetching routines, - or it will get garbage. (a change from GDB version 3, in which - 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. */ -char registers[REGISTER_BYTES + /* SLOP */ 256]; - -/* Nonzero if that register has been fetched. */ -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'. */ -int registers_pid = -1; - -/* Indicate that registers may have changed, so invalidate the cache. */ - -void -registers_changed () -{ - int i; - int numregs = ARCH_NUM_REGS; - - registers_pid = -1; - - for (i = 0; i < numregs; i++) - register_valid[i] = 0; -} - -/* Indicate that all registers have been fetched, so mark them all valid. */ -void -registers_fetched () -{ - int i; - int numregs = ARCH_NUM_REGS; - for (i = 0; i < numregs; i++) - register_valid[i] = 1; -} - -/* Copy LEN bytes of consecutive data from registers - starting with the REGBYTE'th byte of register data - into memory at MYADDR. */ - -void -read_register_bytes (regbyte, myaddr, len) - int regbyte; - char *myaddr; - int len; -{ - /* Fetch all registers. */ - int i, numregs; - - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } - - numregs = ARCH_NUM_REGS; - for (i = 0; i < numregs; i++) - if (!register_valid[i]) - { - target_fetch_registers (-1); - break; - } - if (myaddr != NULL) - memcpy (myaddr, ®isters[regbyte], len); -} - -/* Read register REGNO into memory at MYADDR, which must be large enough - for REGISTER_RAW_BYTES (REGNO). Target byte-order. - If the register is known to be the size of a CORE_ADDR or smaller, - read_register can be used instead. */ -void -read_register_gen (regno, myaddr) - int regno; - char *myaddr; -{ - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } - - if (!register_valid[regno]) - target_fetch_registers (regno); - memcpy (myaddr, ®isters[REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE (regno)); -} - -/* Copy LEN bytes of consecutive data from memory at MYADDR - into registers starting with the REGBYTE'th byte of register data. */ - -void -write_register_bytes (regbyte, myaddr, len) - int regbyte; - char *myaddr; - int len; -{ - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } - - /* Make sure the entire registers array is valid. */ - read_register_bytes (0, (char *)NULL, REGISTER_BYTES); - memcpy (®isters[regbyte], myaddr, len); - target_store_registers (-1); -} - -/* Return the raw contents of register REGNO, regarding it as an integer. */ -/* This probably should be returning LONGEST rather than CORE_ADDR. */ - -CORE_ADDR -read_register (regno) - int regno; -{ - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } - - if (!register_valid[regno]) - target_fetch_registers (regno); - - return extract_address (®isters[REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE(regno)); -} - -CORE_ADDR -read_register_pid (regno, pid) - int regno, pid; -{ - int save_pid; - CORE_ADDR retval; - - if (pid == inferior_pid) - return read_register (regno); - - save_pid = inferior_pid; - - inferior_pid = pid; - - retval = read_register (regno); - - inferior_pid = save_pid; - - return retval; -} - -/* Registers we shouldn't try to store. */ -#if !defined (CANNOT_STORE_REGISTER) -#define CANNOT_STORE_REGISTER(regno) 0 -#endif - -/* Store VALUE, into the raw contents of register number REGNO. */ -/* FIXME: The val arg should probably be a LONGEST. */ - -void -write_register (regno, val) - int regno; - LONGEST val; -{ - PTR buf; - int size; - - /* On the sparc, writing %g0 is a no-op, so we don't even want to change - the registers array if something writes to this register. */ - if (CANNOT_STORE_REGISTER (regno)) - return; - - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } - - size = REGISTER_RAW_SIZE(regno); - buf = alloca (size); - 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. */ - - if (register_valid [regno] - && memcmp (®isters[REGISTER_BYTE (regno)], buf, size) == 0) - return; - - target_prepare_to_store (); - - memcpy (®isters[REGISTER_BYTE (regno)], buf, size); - - register_valid [regno] = 1; - - target_store_registers (regno); -} - -void -write_register_pid (regno, val, pid) - int regno; - LONGEST val; - int pid; -{ - int save_pid; - - if (pid == inferior_pid) - { - write_register (regno, val); - return; - } - - save_pid = inferior_pid; - - inferior_pid = pid; - - write_register (regno, val); - - inferior_pid = save_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. */ - -void -supply_register (regno, val) - int regno; - char *val; -{ - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } - - register_valid[regno] = 1; - memcpy (®isters[REGISTER_BYTE (regno)], val, 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. */ -#ifdef CLEAN_UP_REGISTER_VALUE - CLEAN_UP_REGISTER_VALUE(regno, ®isters[REGISTER_BYTE(regno)]); -#endif -} - - -/* This routine is getting awfully cluttered with #if's. It's probably - time to turn this into READ_PC and define it in the tm.h file. - Ditto for write_pc. */ - -CORE_ADDR -read_pc () -{ -#ifdef TARGET_READ_PC - return TARGET_READ_PC (inferior_pid); -#else - return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, inferior_pid)); -#endif -} - -CORE_ADDR -read_pc_pid (pid) - int pid; -{ -#ifdef TARGET_READ_PC - return TARGET_READ_PC (pid); -#else - return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, pid)); -#endif -} - -void -write_pc (val) - CORE_ADDR val; -{ -#ifdef TARGET_WRITE_PC - TARGET_WRITE_PC (val, inferior_pid); -#else - write_register_pid (PC_REGNUM, (long) val, inferior_pid); -#ifdef NPC_REGNUM - write_register_pid (NPC_REGNUM, (long) val + 4, inferior_pid); -#ifdef NNPC_REGNUM - write_register_pid (NNPC_REGNUM, (long) val + 8, inferior_pid); -#endif -#endif -#endif -} - -void -write_pc_pid (val, pid) - CORE_ADDR val; - int pid; -{ -#ifdef TARGET_WRITE_PC - TARGET_WRITE_PC (val, pid); -#else - write_register_pid (PC_REGNUM, (long) val, pid); -#ifdef NPC_REGNUM - write_register_pid (NPC_REGNUM, (long) val + 4, pid); -#ifdef NNPC_REGNUM - write_register_pid (NNPC_REGNUM, (long) val + 8, pid); -#endif -#endif -#endif -} - -/* Cope with strage ways of getting to the stack and frame pointers */ - -CORE_ADDR -read_sp () -{ -#ifdef TARGET_READ_SP - return TARGET_READ_SP (); -#else - return read_register (SP_REGNUM); -#endif -} - -void -write_sp (val) - CORE_ADDR val; -{ -#ifdef TARGET_WRITE_SP - TARGET_WRITE_SP (val); -#else - write_register (SP_REGNUM, val); -#endif -} - -CORE_ADDR -read_fp () -{ -#ifdef TARGET_READ_FP - return TARGET_READ_FP (); -#else - return read_register (FP_REGNUM); -#endif -} - -void -write_fp (val) - CORE_ADDR val; -{ -#ifdef TARGET_WRITE_FP - TARGET_WRITE_FP (val); -#else - write_register (FP_REGNUM, val); -#endif -} - -/* Will calling read_var_value or locate_var_value on SYM end - up caring what frame it is being evaluated relative to? SYM must - be non-NULL. */ -int -symbol_read_needs_frame (sym) - struct symbol *sym; -{ - switch (SYMBOL_CLASS (sym)) - { - /* All cases listed explicitly so that gcc -Wall will detect it if - we failed to consider one. */ - case LOC_REGISTER: - case LOC_ARG: - case LOC_REF_ARG: - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_LOCAL: - case LOC_LOCAL_ARG: - case LOC_BASEREG: - case LOC_BASEREG_ARG: - return 1; - - case LOC_UNDEF: - case LOC_CONST: - case LOC_STATIC: - case LOC_TYPEDEF: - - case LOC_LABEL: - /* Getting the address of a label can be done independently of the block, - even if some *uses* of that address wouldn't work so well without - the right frame. */ - - case LOC_BLOCK: - case LOC_CONST_BYTES: - case LOC_OPTIMIZED_OUT: - return 0; - } - return 1; -} - -/* Given a struct symbol for a variable, - and a stack frame id, read the value of the variable - and return a (pointer to a) struct value containing the value. - If the variable cannot be found, return a zero pointer. - If FRAME is NULL, use the selected_frame. */ - -value_ptr -read_var_value (var, frame) - register struct symbol *var; - FRAME frame; -{ - register value_ptr v; - struct frame_info *fi; - struct type *type = SYMBOL_TYPE (var); - CORE_ADDR addr; - register int len; - - v = allocate_value (type); - VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */ - len = TYPE_LENGTH (type); - - if (frame == 0) frame = selected_frame; - - switch (SYMBOL_CLASS (var)) - { - case LOC_CONST: - /* Put the constant back in target format. */ - store_signed_integer (VALUE_CONTENTS_RAW (v), len, - (LONGEST) SYMBOL_VALUE (var)); - VALUE_LVAL (v) = not_lval; - return v; - - case LOC_LABEL: - /* Put the constant back in target format. */ - store_address (VALUE_CONTENTS_RAW (v), len, SYMBOL_VALUE_ADDRESS (var)); - VALUE_LVAL (v) = not_lval; - return v; - - case LOC_CONST_BYTES: - { - char *bytes_addr; - bytes_addr = SYMBOL_VALUE_BYTES (var); - memcpy (VALUE_CONTENTS_RAW (v), bytes_addr, len); - VALUE_LVAL (v) = not_lval; - return v; - } - - case LOC_STATIC: - addr = SYMBOL_VALUE_ADDRESS (var); - break; - - case LOC_ARG: - fi = get_frame_info (frame); - if (fi == NULL) - return 0; - addr = FRAME_ARGS_ADDRESS (fi); - if (!addr) - { - return 0; - } - addr += SYMBOL_VALUE (var); - break; - - case LOC_REF_ARG: - fi = get_frame_info (frame); - if (fi == NULL) - return 0; - addr = FRAME_ARGS_ADDRESS (fi); - if (!addr) - { - return 0; - } - addr += SYMBOL_VALUE (var); - addr = read_memory_unsigned_integer - (addr, TARGET_PTR_BIT / TARGET_CHAR_BIT); - break; - - case LOC_LOCAL: - case LOC_LOCAL_ARG: - fi = get_frame_info (frame); - if (fi == NULL) - return 0; - addr = FRAME_LOCALS_ADDRESS (fi); - addr += SYMBOL_VALUE (var); - break; - - case LOC_BASEREG: - case LOC_BASEREG_ARG: - { - 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)); - return v; - - case LOC_REGISTER: - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - { - struct block *b; - - 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)); - VALUE_LVAL (v) = lval_memory; - } - else - return value_from_register (type, SYMBOL_VALUE (var), frame); - } - break; - - case LOC_OPTIMIZED_OUT: - VALUE_LVAL (v) = not_lval; - VALUE_OPTIMIZED_OUT (v) = 1; - return v; - - default: - error ("Cannot look up value of a botched symbol."); - break; - } - - VALUE_ADDRESS (v) = addr; - VALUE_LAZY (v) = 1; - return v; -} - -/* Return a value of type TYPE, stored in register REGNUM, in frame - FRAME. */ - -value_ptr -value_from_register (type, regnum, frame) - struct type *type; - int regnum; - FRAME frame; -{ - char raw_buffer [MAX_REGISTER_RAW_SIZE]; - CORE_ADDR addr; - int optim; - value_ptr v = allocate_value (type); - int len = TYPE_LENGTH (type); - char *value_bytes = 0; - int value_bytes_copied = 0; - int num_storage_locs; - enum lval_type lval; - - VALUE_REGNO (v) = regnum; - - num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ? - ((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 : - 1); - - if (num_storage_locs > 1 -#ifdef GDB_TARGET_IS_H8500 - || TYPE_CODE (type) == TYPE_CODE_PTR -#endif - ) - { - /* Value spread across multiple storage locations. */ - - int local_regnum; - int mem_stor = 0, reg_stor = 0; - int mem_tracking = 1; - CORE_ADDR last_addr = 0; - CORE_ADDR first_addr = 0; - - value_bytes = (char *) alloca (len + MAX_REGISTER_RAW_SIZE); - - /* Copy all of the data out, whereever it may be. */ - -#ifdef GDB_TARGET_IS_H8500 -/* This piece of hideosity is required because the H8500 treats registers - differently depending upon whether they are used as pointers or not. As a - pointer, a register needs to have a page register tacked onto the front. - An alternate way to do this would be to have gcc output different register - numbers for the pointer & non-pointer form of the register. But, it - doesn't, so we're stuck with this. */ - - if (TYPE_CODE (type) == TYPE_CODE_PTR - && len > 2) - { - int page_regnum; - - switch (regnum) - { - case R0_REGNUM: case R1_REGNUM: case R2_REGNUM: case R3_REGNUM: - page_regnum = SEG_D_REGNUM; - break; - case R4_REGNUM: case R5_REGNUM: - page_regnum = SEG_E_REGNUM; - break; - case R6_REGNUM: case R7_REGNUM: - page_regnum = SEG_T_REGNUM; - break; - } - - value_bytes[0] = 0; - get_saved_register (value_bytes + 1, - &optim, - &addr, - frame, - page_regnum, - &lval); - - if (lval == lval_register) - reg_stor++; - else - mem_stor++; - first_addr = addr; - last_addr = addr; - - get_saved_register (value_bytes + 2, - &optim, - &addr, - frame, - regnum, - &lval); - - if (lval == lval_register) - reg_stor++; - else - { - mem_stor++; - mem_tracking = mem_tracking && (addr == last_addr); - } - last_addr = addr; - } - else -#endif /* GDB_TARGET_IS_H8500 */ - for (local_regnum = regnum; - value_bytes_copied < len; - (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum), - ++local_regnum)) - { - get_saved_register (value_bytes + value_bytes_copied, - &optim, - &addr, - frame, - local_regnum, - &lval); - - if (regnum == local_regnum) - first_addr = addr; - if (lval == lval_register) - reg_stor++; - else - { - mem_stor++; - - mem_tracking = - (mem_tracking - && (regnum == local_regnum - || addr == last_addr)); - } - last_addr = addr; - } - - if ((reg_stor && mem_stor) - || (mem_stor && !mem_tracking)) - /* Mixed storage; all of the hassle we just went through was - for some good purpose. */ - { - VALUE_LVAL (v) = lval_reg_frame_relative; - VALUE_FRAME (v) = FRAME_FP (frame); - VALUE_FRAME_REGNUM (v) = regnum; - } - else if (mem_stor) - { - VALUE_LVAL (v) = lval_memory; - VALUE_ADDRESS (v) = first_addr; - } - else if (reg_stor) - { - VALUE_LVAL (v) = lval_register; - VALUE_ADDRESS (v) = first_addr; - } - else - fatal ("value_from_register: Value not stored anywhere!"); - - VALUE_OPTIMIZED_OUT (v) = optim; - - /* Any structure stored in more than one register will always be - an integral number of registers. Otherwise, you'd need to do - some fiddling with the last register copied here for little - endian machines. */ - - /* Copy into the contents section of the value. */ - memcpy (VALUE_CONTENTS_RAW (v), value_bytes, len); - - /* Finally do any conversion necessary when extracting this - type from more than one register. */ -#ifdef REGISTER_CONVERT_TO_TYPE - REGISTER_CONVERT_TO_TYPE(regnum, type, VALUE_CONTENTS_RAW(v)); -#endif - return v; - } - - /* Data is completely contained within a single register. Locate the - register's contents in a real register or in core; - read the data in raw format. */ - - get_saved_register (raw_buffer, &optim, &addr, frame, regnum, &lval); - VALUE_OPTIMIZED_OUT (v) = optim; - VALUE_LVAL (v) = lval; - VALUE_ADDRESS (v) = addr; - - /* Convert raw data to virtual format if necessary. */ - -#ifdef REGISTER_CONVERTIBLE - if (REGISTER_CONVERTIBLE (regnum)) - { - REGISTER_CONVERT_TO_VIRTUAL (regnum, type, - raw_buffer, VALUE_CONTENTS_RAW (v)); - } - else -#endif - { - /* Raw and virtual formats are the same for this register. */ - -#if TARGET_BYTE_ORDER == BIG_ENDIAN - if (len < REGISTER_RAW_SIZE (regnum)) - { - /* Big-endian, and we want less than full size. */ - VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len; - } -#endif - - memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len); - } - - return v; -} - -/* Given a struct symbol for a variable or function, - and a stack frame id, - return a (pointer to a) struct value containing the properly typed - address. */ - -value_ptr -locate_var_value (var, frame) - register struct symbol *var; - FRAME frame; -{ - CORE_ADDR addr = 0; - struct type *type = SYMBOL_TYPE (var); - value_ptr lazy_value; - - /* Evaluate it first; if the result is a memory address, we're fine. - Lazy evaluation pays off here. */ - - lazy_value = read_var_value (var, frame); - if (lazy_value == 0) - error ("Address of \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var)); - - if (VALUE_LAZY (lazy_value) - || TYPE_CODE (type) == TYPE_CODE_FUNC) - { - addr = VALUE_ADDRESS (lazy_value); - return value_from_longest (lookup_pointer_type (type), (LONGEST) addr); - } - - /* Not a memory address; check what the problem was. */ - switch (VALUE_LVAL (lazy_value)) - { - case lval_register: - case lval_reg_frame_relative: - error ("Address requested for identifier \"%s\" which is in a register.", - SYMBOL_SOURCE_NAME (var)); - break; - - default: - error ("Can't take address of \"%s\" which isn't an lvalue.", - SYMBOL_SOURCE_NAME (var)); - break; - } - return 0; /* For lint -- never reached */ -} diff --git a/gnu/usr.bin/gdb/gdb/floatformat.h b/gnu/usr.bin/gdb/gdb/floatformat.h deleted file mode 100644 index a0a53dc..0000000 --- a/gnu/usr.bin/gdb/gdb/floatformat.h +++ /dev/null @@ -1,87 +0,0 @@ -/* IEEE floating point support declarations, for GDB, the GNU Debugger. - Copyright (C) 1991 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 (FLOATFORMAT_H) -#define FLOATFORMAT_H 1 - -#include "ansidecl.h" - -/* A floatformat consists of a sign bit, an exponent and a mantissa. Once the - bytes are concatenated according to the byteorder flag, then each of those - fields is contiguous. We number the bits with 0 being the most significant - (i.e. BITS_BIG_ENDIAN type numbering), and specify which bits each field - contains with the *_start and *_len fields. */ - -enum floatformat_byteorders { floatformat_little, floatformat_big }; - -enum floatformat_intbit { floatformat_intbit_yes, floatformat_intbit_no }; - -struct floatformat -{ - enum floatformat_byteorders byteorder; - unsigned int totalsize; /* Total size of number in bits */ - - /* Sign bit is always one bit long. 1 means negative, 0 means positive. */ - unsigned int sign_start; - - unsigned int exp_start; - unsigned int exp_len; - /* Amount added to "true" exponent. 0x3fff for many IEEE extendeds. */ - unsigned int exp_bias; - /* Exponent value which indicates NaN. This is the actual value stored in - the float, not adjusted by the exp_bias. This usually consists of all - one bits. */ - unsigned int exp_nan; - - unsigned int man_start; - unsigned int man_len; - - /* Is the integer bit explicit or implicit? */ - enum floatformat_intbit intbit; -}; - -/* floatformats for IEEE single and double, big and little endian. */ - -extern const struct floatformat floatformat_ieee_single_big; -extern const struct floatformat floatformat_ieee_single_little; -extern const struct floatformat floatformat_ieee_double_big; -extern const struct floatformat floatformat_ieee_double_little; - -/* floatformats for various extendeds. */ - -extern const struct floatformat floatformat_i387_ext; -extern const struct floatformat floatformat_m68881_ext; -extern const struct floatformat floatformat_i960_ext; -extern const struct floatformat floatformat_m88110_ext; - -/* Convert from FMT to a double. - FROM is the address of the extended float. - Store the double in *TO. */ - -extern void -floatformat_to_double PARAMS ((const struct floatformat *, char *, double *)); - -/* The converse: convert the double *FROM to FMT - and store where TO points. */ - -extern void -floatformat_from_double PARAMS ((const struct floatformat *, - double *, char *)); - -#endif /* defined (FLOATFORMAT_H) */ diff --git a/gnu/usr.bin/gdb/gdb/fopen-bin.h b/gnu/usr.bin/gdb/gdb/fopen-bin.h deleted file mode 100644 index 2b8a8e2..0000000 --- a/gnu/usr.bin/gdb/gdb/fopen-bin.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Macros for the 'type' part of an fopen, freopen or fdopen. - - [Update] - - This version is for "binary" systems, where text and binary files are - different. An example is Mess-Dose. Many Unix systems could also - cope with a "b" in the string, indicating binary files, but some reject this - (and thereby don't conform to ANSI C, but what else is new?). - - This file is designed for inclusion by host-dependent .h files. No - user application should include it directly, since that would make - the application unable to be configured for both "same" and "binary" - variant systems. */ - -#define FOPEN_RB "rb" -#define FOPEN_WB "wb" -#define FOPEN_AB "ab" -#define FOPEN_RUB "r+b" -#define FOPEN_WUB "w+b" -#define FOPEN_AUB "a+b" - -#define FOPEN_RT "r" -#define FOPEN_WT "w" -#define FOPEN_AT "a" -#define FOPEN_RUT "r+" -#define FOPEN_WUT "w+" -#define FOPEN_AUT "a+" diff --git a/gnu/usr.bin/gdb/gdb/fopen-same.h b/gnu/usr.bin/gdb/gdb/fopen-same.h deleted file mode 100644 index c296678..0000000 --- a/gnu/usr.bin/gdb/gdb/fopen-same.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Macros for the 'type' part of an fopen, freopen or fdopen. - - [Update] - - This version is for "same" systems, where text and binary files are - the same. An example is Unix. Many Unix systems could also add a - "b" to the string, indicating binary files, but some reject this - (and thereby don't conform to ANSI C, but what else is new?). - - This file is designed for inclusion by host-dependent .h files. No - user application should include it directly, since that would make - the application unable to be configured for both "same" and "binary" - variant systems. */ - -#define FOPEN_RB "r" -#define FOPEN_WB "w" -#define FOPEN_AB "a" -#define FOPEN_RUB "r+" -#define FOPEN_WUB "w+" -#define FOPEN_AUB "a+" - -#define FOPEN_RT "r" -#define FOPEN_WT "w" -#define FOPEN_AT "a" -#define FOPEN_RUT "r+" -#define FOPEN_WUT "w+" -#define FOPEN_AUT "a+" diff --git a/gnu/usr.bin/gdb/gdb/fork-child.c b/gnu/usr.bin/gdb/gdb/fork-child.c deleted file mode 100644 index bca1841..0000000 --- a/gnu/usr.bin/gdb/gdb/fork-child.c +++ /dev/null @@ -1,300 +0,0 @@ -/* Fork a Unix child process, and set up to debug it, for GDB. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include -#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 - -extern char **environ; - -#ifndef SHELL_FILE -#define SHELL_FILE "/bin/sh" -#endif - -/* 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. - ENV is the environment vector to pass. SHELL_FILE is the shell file, - or NULL if we should pick one. Errors reported with error(). */ - -void -fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun, - shell_file) - char *exec_file; - char *allargs; - char **env; - void (*traceme_fun) PARAMS ((void)); - void (*init_trace_fun) PARAMS ((int)); - char *shell_file; -{ - int pid; - char *shell_command; - static char default_shell_file[] = SHELL_FILE; - int len; - /* Set debug_fork then attach to the child while it sleeps, to debug. */ - static int debug_fork = 0; - /* This is set to the result of setpgrp, which if vforked, will be visible - to you in the parent process. It's only used by humans for debugging. */ - static int debug_setpgrp = 657473; - char **save_our_env; - - /* 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; - - /* 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 - every character being '. */ - len = 5 + 4 * strlen (exec_file) + 1 + strlen (allargs) + 1 + /*slop*/ 12; - /* If desired, concat something onto the front of ALLARGS. - SHELL_COMMAND is the result. */ -#ifdef SHELL_COMMAND_CONCAT - shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + len); - strcpy (shell_command, SHELL_COMMAND_CONCAT); -#else - 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; - - /* 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); - - /* 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 - restore it. */ - save_our_env = environ; - - /* Tell the terminal handling subsystem what tty we plan to run on; - it will just record the information for later. */ - - new_tty_prefork (inferior_io_terminal); - - /* 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); - -#if defined(USG) && !defined(HAVE_VFORK) - pid = fork (); -#else - if (debug_fork) - pid = fork (); - else - pid = vfork (); -#endif - - if (pid < 0) - perror_with_name ("vfork"); - - if (pid == 0) - { - 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"); - - /* Ask the tty subsystem to switch to the one we specified earlier - (or to share the current terminal, if none was specified). */ - - new_tty (); - - /* Changing the signal handlers for the inferior after - a vfork can also change them for the superior, so we don't mess - with signals here. See comments in - initialize_signals for how we get the right signal handlers - for the inferior. */ - - /* "Trace me, Dr. Memory!" */ - (*traceme_fun) (); - - /* There is no execlpe call, so we have to set the environment - for our child in the global variable. If we've vforked, this - clobbers the parent, but environ is restored a few lines down - 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); - } - - /* Restore our environment in case a vforked child clob'd it. */ - environ = save_our_env; - - 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); - - /* We are now in the child process of interest, having exec'd the - correct program, and are poised at the first instruction of the - new program. */ -#ifdef SOLIB_CREATE_INFERIOR_HOOK - SOLIB_CREATE_INFERIOR_HOOK (pid); -#endif -} - -/* Accept NTRAPS traps from the inferior. */ - -void -startup_inferior (ntraps) - int ntraps; -{ - int pending_execs = ntraps; - int terminal_initted; - - /* The process was started by the fork that created it, - but it will have stopped one instruction after execing the shell. - Here we must get it up to actual execution of the real program. */ - - clear_proceed_status (); - - init_wait_for_inferior (); - - terminal_initted = 0; - -#ifdef STARTUP_INFERIOR - STARTUP_INFERIOR (pending_execs); -#else - while (1) - { - stop_soon_quietly = 1; /* Make wait_for_inferior be quiet */ - wait_for_inferior (); - if (stop_signal != TARGET_SIGNAL_TRAP) - { - /* Let shell child handle its own signals in its own way */ - /* FIXME, what if child has exit()ed? Must exit loop somehow */ - resume (0, stop_signal); - } - else - { - /* We handle SIGTRAP, however; it means child did an exec. */ - if (!terminal_initted) - { - /* Now that the child has exec'd we know it has already set its - process group. On POSIX systems, tcsetpgrp will fail with - EPERM if we try it before the child's setpgid. */ - - /* 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 (); - - terminal_initted = 1; - } - if (0 == --pending_execs) - break; - resume (0, TARGET_SIGNAL_0); /* Just make it go on */ - } - } -#endif /* STARTUP_INFERIOR */ - stop_soon_quietly = 0; -} diff --git a/gnu/usr.bin/gdb/gdb/frame.h b/gnu/usr.bin/gdb/gdb/frame.h deleted file mode 100644 index a46ed17..0000000 --- a/gnu/usr.bin/gdb/gdb/frame.h +++ /dev/null @@ -1,240 +0,0 @@ -/* Definitions for dealing with stack frames, for GDB, the GNU debugger. - Copyright 1986, 1989, 1991, 1992 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 (FRAME_H) -#define FRAME_H 1 - -/* A FRAME identifies a specific stack frame. It is not constant over - calls to the inferior (frame addresses are, see below). - - This is implemented as a "struct frame_info *". This file and - blockframe.c are the only places which are allowed to use the - equivalence between FRAME and struct frame_info *. Exception: - Prototypes in other files use "struct frame_info *" because this - file might not be included. - - The distinction between a FRAME and a "struct frame_info *" is made - with the idea of maybe someday changing a FRAME to be something else, - but seems to me that a "struct frame_info *" is fully general (since - any necessarily fields can be added; changing the meaning of existing - fields is not helped by the FRAME distinction), and this distinction - merely creates unnecessary hair. -kingdon, 18 May 93. */ -typedef struct frame_info *FRAME; - -/* Convert from a "struct frame_info *" into a FRAME. */ -#define FRAME_INFO_ID(f) (f) - -/* Convert from a FRAME into a "struct frame_info *". */ -extern struct frame_info * -get_frame_info PARAMS ((FRAME)); - -/* Type of the address of a frame. It is widely assumed (at least in - prototypes in headers which might not include this header) that - this is the same as CORE_ADDR, and no one can think of a case in - which it wouldn't be, so it might be best to remove this typedef. */ -typedef CORE_ADDR FRAME_ADDR; - -/* Convert from a FRAME into a frame address. Except in the - machine-dependent *FRAME* macros, a frame address has no defined - meaning other than as a magic cookie which identifies a frame over - calls to the inferior. The only known exception is inferior.h - (PC_IN_CALL_DUMMY) [ON_STACK]; see comments there. You cannot - assume that a frame address contains enough information to - reconstruct the frame; if you want more than just to identify the - frame (e.g. be able to fetch variables relative to that frame), - then save the whole struct frame_info (and the next struct - frame_info, since the latter is used for fetching variables on some - machines). */ - -#define FRAME_FP(fr) ((fr)->frame) - -/* 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 - points to it. Additional frames get allocated (in - get_prev_frame_info) as needed, and are chained through the next - and prev fields. Any time that the frame cache becomes invalid - (most notably when we execute something, but also if we change how - we interpret the frames (e.g. "set heuristic-fence-post" in - mips-tdep.c, or anything which reads new symbols)), we should call - reinit_frame_cache. */ - -struct frame_info - { - /* Nominal address of the frame described. See comments at FRAME_FP - about what this means outside the *FRAME* macros; in the *FRAME* - macros, it can mean whatever makes most sense for this machine. */ - FRAME_ADDR frame; - - /* Address at which execution is occurring in this frame. - For the innermost frame, it's the current pc. - For other frames, it is a pc saved in the next frame. */ - CORE_ADDR pc; - - /* Nonzero if this is a frame associated with calling a signal handler. - - Set by machine-dependent code. On some machines, if - the machine-dependent code fails to check for this, the backtrace - will look relatively normal. For example, on the i386 - #3 0x158728 in sighold () - On other machines (e.g. rs6000), the machine-dependent code better - set this to prevent us from trying to print it like a normal frame. */ - int signal_handler_caller; - - /* 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. */ - - /* Pointers to the next and previous frame_info's in the frame cache. */ - FRAME next, prev; - }; - -/* Describe the saved registers of a frame. */ - -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]; - }; - -/* Define 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. - - If a particular target needs a different definition, then it can override - the definition here by providing one in the tm file. */ - -#if !defined (FRAME_CHAIN_VALID) - -#if defined (FRAME_CHAIN_VALID_ALTERNATE) - -/* 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))) - -#endif /* FRAME_CHAIN_VALID_ALTERNATE */ - -#endif /* FRAME_CHAIN_VALID */ - -/* The stack frame that the user has specified for commands to act on. - Note that one cannot assume this is the address of valid data. */ - -extern FRAME selected_frame; - -/* Level of the selected frame: - 0 for innermost, 1 for its caller, ... - or -1 for frame specified by address with no defined level. */ - -extern int selected_frame_level; - -extern struct frame_info * -get_prev_frame_info PARAMS ((FRAME)); - -extern FRAME -create_new_frame PARAMS ((FRAME_ADDR, CORE_ADDR)); - -extern void -flush_cached_frames PARAMS ((void)); - -extern void -reinit_frame_cache PARAMS ((void)); - -extern void -get_frame_saved_regs PARAMS ((struct frame_info *, struct frame_saved_regs *)); - -extern void -set_current_frame PARAMS ((FRAME)); - -extern FRAME -get_prev_frame PARAMS ((FRAME)); - -extern FRAME -get_current_frame PARAMS ((void)); - -extern FRAME -get_next_frame PARAMS ((FRAME)); - -extern struct block * -get_frame_block PARAMS ((FRAME)); - -extern struct block * -get_current_block PARAMS ((void)); - -extern struct block * -get_selected_block PARAMS ((void)); - -extern struct symbol * -get_frame_function PARAMS ((FRAME)); - -extern CORE_ADDR -get_frame_pc PARAMS ((FRAME)); - -extern CORE_ADDR -get_pc_function_start PARAMS ((CORE_ADDR)); - -extern struct block * block_for_pc PARAMS ((CORE_ADDR)); - -extern int frameless_look_for_prologue PARAMS ((FRAME)); - -extern void print_frame_args PARAMS ((struct symbol *, struct frame_info *, - int, GDB_FILE *)); - -extern FRAME find_relative_frame PARAMS ((FRAME, int*)); - -extern void print_stack_frame PARAMS ((FRAME, int, int)); - -extern void select_frame PARAMS ((FRAME, int)); - -extern void record_selected_frame PARAMS ((FRAME_ADDR *, int *)); - -extern void print_frame_info PARAMS ((struct frame_info *, int, int, int)); - -extern CORE_ADDR find_saved_register PARAMS ((FRAME, int)); - -extern FRAME block_innermost_frame PARAMS ((struct block *)); - -extern FRAME find_frame_addr_in_frame_chain PARAMS ((FRAME_ADDR)); - -extern CORE_ADDR sigtramp_saved_pc PARAMS ((FRAME)); - -#endif /* !defined (FRAME_H) */ diff --git a/gnu/usr.bin/gdb/gdb/freebsd-nat.c b/gnu/usr.bin/gdb/gdb/freebsd-nat.c deleted file mode 100644 index 323f751..0000000 --- a/gnu/usr.bin/gdb/gdb/freebsd-nat.c +++ /dev/null @@ -1,802 +0,0 @@ -/* Native-dependent code for BSD Unix running on i386's, for GDB. - Copyright 1988, 1989, 1991, 1992 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. - - $FreeBSD$ -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "defs.h" -#include "symtab.h" - -/* this table must line up with REGISTER_NAMES in tm-i386v.h */ -/* symbols like 'tEAX' come from */ -static int tregmap[] = -{ - tEAX, tECX, tEDX, tEBX, - tESP, tEBP, tESI, tEDI, - tEIP, tEFLAGS, tCS, tSS, - tDS, tES, tSS, tSS, /* lies: no fs or gs */ -}; - -/* blockend is the value of u.u_ar0, and points to the - place where ES is stored. */ - -int -i386_register_u_addr (blockend, regnum) - int blockend; - int regnum; -{ - return (blockend + 4 * tregmap[regnum]); -} - - -#define fpstate save87 -#define U_FPSTATE(u) u.u_pcb.pcb_savefpu - -static void -i387_to_double (from, to) - char *from; - char *to; -{ - long *lp; - /* push extended mode on 387 stack, then pop in double mode - * - * first, set exception masks so no error is generated - - * number will be rounded to inf or 0, if necessary - */ - asm ("pushl %eax"); /* grab a stack slot */ - asm ("fstcw (%esp)"); /* get 387 control word */ - asm ("movl (%esp),%eax"); /* save old value */ - asm ("orl $0x3f,%eax"); /* mask all exceptions */ - asm ("pushl %eax"); - asm ("fldcw (%esp)"); /* load new value into 387 */ - - asm ("movl 8(%ebp),%eax"); - asm ("fldt (%eax)"); /* push extended number on 387 stack */ - asm ("fwait"); - asm ("movl 12(%ebp),%eax"); - asm ("fstpl (%eax)"); /* pop double */ - asm ("fwait"); - - asm ("popl %eax"); /* flush modified control word */ - asm ("fnclex"); /* clear exceptions */ - asm ("fldcw (%esp)"); /* restore original control word */ - asm ("popl %eax"); /* flush saved copy */ -} - -#if 0 -static void -double_to_i387 (from, to) - char *from; - char *to; -{ - /* push double mode on 387 stack, then pop in extended mode - * no errors are possible because every 64-bit pattern - * can be converted to an extended - */ - asm ("movl 8(%ebp),%eax"); - asm ("fldl (%eax)"); - asm ("fwait"); - asm ("movl 12(%ebp),%eax"); - asm ("fstpt (%eax)"); - asm ("fwait"); -} -#endif - -struct env387 -{ - unsigned short control; - unsigned short r0; - unsigned short status; - unsigned short r1; - unsigned short tag; - unsigned short r2; - unsigned long eip; - unsigned short code_seg; - unsigned short opcode; - unsigned long operand; - unsigned short operand_seg; - unsigned short r3; - unsigned char regs[8][10]; -}; - -/* static */ void -print_387_control_word (control) -unsigned int control; -{ - printf ("control 0x%04x: ", control); - printf ("compute to "); - switch ((control >> 8) & 3) - { - case 0: printf ("24 bits; "); break; - case 1: printf ("(bad); "); break; - case 2: printf ("53 bits; "); break; - case 3: printf ("64 bits; "); break; - } - printf ("round "); - switch ((control >> 10) & 3) - { - case 0: printf ("NEAREST; "); break; - case 1: printf ("DOWN; "); break; - case 2: printf ("UP; "); break; - case 3: printf ("CHOP; "); break; - } - if (control & 0x3f) - { - printf ("mask:"); - if (control & 0x0001) printf (" INVALID"); - if (control & 0x0002) printf (" DENORM"); - if (control & 0x0004) printf (" DIVZ"); - if (control & 0x0008) printf (" OVERF"); - if (control & 0x0010) printf (" UNDERF"); - if (control & 0x0020) printf (" LOS"); - printf (";"); - } - printf ("\n"); - if (control & 0xe080) printf ("warning: reserved bits on 0x%x\n", - control & 0xe080); -} - -/* static */ void -print_387_status_word (status) - unsigned int status; -{ - printf ("status 0x%04x: ", status); - if (status & 0xff) - { - printf ("exceptions:"); - if (status & 0x0001) printf (" INVALID"); - if (status & 0x0002) printf (" DENORM"); - if (status & 0x0004) printf (" DIVZ"); - if (status & 0x0008) printf (" OVERF"); - if (status & 0x0010) printf (" UNDERF"); - if (status & 0x0020) printf (" LOS"); - if (status & 0x0040) printf (" FPSTACK"); - printf ("; "); - } - printf ("flags: %d%d%d%d; ", - (status & 0x4000) != 0, - (status & 0x0400) != 0, - (status & 0x0200) != 0, - (status & 0x0100) != 0); - - printf ("top %d\n", (status >> 11) & 7); -} - -static void -print_387_status (status, ep) - unsigned short status; - struct env387 *ep; -{ - int i; - int bothstatus; - int top; - int fpreg; - unsigned char *p; - - bothstatus = ((status != 0) && (ep->status != 0)); - if (status != 0) - { - if (bothstatus) - printf ("u: "); - print_387_status_word ((unsigned int)status); - } - - if (ep->status != 0) - { - if (bothstatus) - printf ("e: "); - print_387_status_word ((unsigned int)ep->status); - } - - print_387_control_word ((unsigned int)ep->control); - printf ("opcode 0x%x; ", ep->opcode); - printf ("pc 0x%x:0x%x; ", ep->code_seg, ep->eip); - printf ("operand 0x%x:0x%x\n", ep->operand_seg, ep->operand); - - top = (ep->status >> 11) & 7; - - printf (" regno tag msb lsb value\n"); - for (fpreg = 7; fpreg >= 0; fpreg--) - { - int st_regno; - double val; - - /* The physical regno `fpreg' is only relevant as an index into the - * tag word. Logical `%st' numbers are required for indexing ep->regs. - */ - st_regno = (fpreg + 8 - top) & 7; - - printf ("%%st(%d) %s ", st_regno, fpreg == top ? "=>" : " "); - - switch ((ep->tag >> (fpreg * 2)) & 3) - { - case 0: printf ("valid "); break; - case 1: printf ("zero "); break; - case 2: printf ("trap "); break; - case 3: printf ("empty "); break; - } - for (i = 9; i >= 0; i--) - printf ("%02x", ep->regs[st_regno][i]); - - i387_to_double (ep->regs[st_regno], (char *)&val); - printf (" %g\n", val); - } -} - -void -i386_float_info () -{ - struct user u; /* just for address computations */ - int i; - /* fpstate defined in */ - struct fpstate *fpstatep; - char buf[sizeof (struct fpstate) + 2 * sizeof (int)]; - unsigned int uaddr; - char fpvalid; - unsigned int rounded_addr; - unsigned int rounded_size; - /*extern int corechan;*/ - int skip; - extern int inferior_pid; - - uaddr = (char *)&U_FPSTATE(u) - (char *)&u; - if (inferior_pid) - { - int *ip; - - rounded_addr = uaddr & -sizeof (int); - rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) + - sizeof (int) - 1) / sizeof (int); - skip = uaddr - rounded_addr; - - ip = (int *)buf; - for (i = 0; i < rounded_size; i++) - { - *ip++ = ptrace (PT_READ_U, inferior_pid, (caddr_t)rounded_addr, 0); - rounded_addr += sizeof (int); - } - } - else - { -#if 1 - printf("float info: can't do a core file (yet)\n"); - return; -#else - if (lseek (corechan, uaddr, 0) < 0) - perror_with_name ("seek on core file"); - if (myread (corechan, buf, sizeof (struct fpstate)) < 0) - perror_with_name ("read from core file"); - skip = 0; -#endif - } - - fpstatep = (struct fpstate *)(buf + skip); - print_387_status (fpstatep->sv_ex_sw, (struct env387 *)fpstatep); -} - -#ifdef SETUP_ARBITRARY_FRAME -FRAME -setup_arbitrary_frame (numargs, args) -int numargs; -unsigned int *args; -{ - if (numargs > 2) - error ("Too many args in frame specification"); - return create_new_frame ((CORE_ADDR)args[0], (CORE_ADDR)args[1]); -} -#endif - -#ifdef KERNEL_DEBUG -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#define KERNOFF ((unsigned)KERNBASE) -#define INKERNEL(x) ((x) >= KERNOFF) - -static CORE_ADDR sbr; -static CORE_ADDR curpcb; -static CORE_ADDR kstack; -static int found_pcb; -static int devmem; -static int kfd; -static struct pcb pcb; -int read_pcb (int, CORE_ADDR); -static CORE_ADDR kvtophys (int, CORE_ADDR); -static physrd(int, u_int, char*, int); - -extern CORE_ADDR ksym_lookup(const char *); - -/* substitutes for the stuff in libkvm which doesn't work */ -/* most of this was taken from the old kgdb */ - -/* we don't need all this stuff, but the call should look the same */ -kvm_open (efile, cfile, sfile, perm, errout) -char *efile; -char *cfile; -char *sfile; /* makes this kvm_open more compatible to the one in libkvm */ -int perm; -char *errout; /* makes this kvm_open more compatible to the one in libkvm */ -{ - struct stat stb; - CORE_ADDR addr; - int cfd; - - if ((cfd = open(cfile, perm, 0)) < 0) - return (cfd); - - fstat(cfd, &stb); - if ((stb.st_mode & S_IFMT) == S_IFCHR && stb.st_rdev == makedev(2, 0)) { - devmem = 1; - kfd = open ("/dev/kmem", perm, 0); - } - - physrd(cfd, ksym_lookup("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr); - printf("IdlePTD %x\n", sbr); - curpcb = ksym_lookup("curpcb") - KERNOFF; - physrd(cfd, curpcb, (char*)&curpcb, sizeof curpcb); - kstack = ksym_lookup("kstack"); - - found_pcb = 1; /* for vtophys */ - if (!devmem) - read_pcb(cfd, ksym_lookup("dumppcb") - KERNOFF); - else - read_pcb(cfd, kvtophys(cfd, kstack)); - - return (cfd); -} - -kvm_close (fd) -{ - return (close (fd)); -} - -kvm_write(core_kd, memaddr, myaddr, len) -CORE_ADDR memaddr; -char *myaddr; -{ - int cc; - - if (devmem) { - if (kfd > 0) { - /* - * Just like kvm_read, only we write. - */ - errno = 0; - if (lseek(kfd, (off_t)memaddr, 0) < 0 && errno != 0) { - error("kvm_write:invalid address (%x)", memaddr); - return (0); - } - cc = write(kfd, myaddr, len); - if (cc < 0) { - error("kvm_write:write failed"); - return (0); - } else if (cc < len) - error("kvm_write:short write"); - return (cc); - } else - return (0); - } else { - printf("kvm_write not implemented for dead kernels\n"); - return (0); - } - /* NOTREACHED */ -} - -kvm_read(core_kd, memaddr, myaddr, len) -CORE_ADDR memaddr; -char *myaddr; -{ - return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); -} - -kvm_uread(core_kd, p, memaddr, myaddr, len) -register struct proc *p; -CORE_ADDR memaddr; -char *myaddr; -{ - register char *cp; - char procfile[MAXPATHLEN]; - ssize_t amount; - int fd; - - if (devmem) { - cp = myaddr; - - sprintf(procfile, "/proc/%d/mem", p->p_pid); - fd = open(procfile, O_RDONLY, 0); - - if (fd < 0) { - error("cannot open %s", procfile); - close(fd); - return (0); - } - - while (len > 0) { - if (lseek(fd, memaddr, 0) == -1 && errno != 0) { - error("invalid address (%x) in %s", - memaddr, procfile); - break; - } - amount = read(fd, cp, len); - if (amount < 0) { - error("error reading %s", procfile); - break; - } - cp += amount; - memaddr += amount; - len -= amount; - } - - close(fd); - return (ssize_t)(cp - myaddr); - } else { - return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); - } -} - -static struct kinfo_proc kp; - -/* - * try to do what kvm_proclist in libkvm would do - */ -int -kvm_proclist (cfd, pid, p, cnt) -int cfd, pid, *cnt; -struct proc *p; -{ - struct proc lp; - - for (; p != NULL; p = lp.p_list.le_next) { - if (!kvm_read(cfd, (CORE_ADDR)p, (char *)&lp, sizeof (lp))) - return (0); - if (lp.p_pid != pid) - continue; - kp.kp_eproc.e_paddr = p; - *cnt = 1; - return (1); - } - *cnt = 0; - return (0); -} - -/* - * try to do what kvm_deadprocs in libkvm would do - */ -struct kinfo_proc * -kvm_deadprocs (cfd, pid, cnt) -int cfd, pid, *cnt; -{ - CORE_ADDR allproc, zombproc; - struct proc *p; - - allproc = ksym_lookup("allproc"); - if (kvm_read(cfd, allproc, (char *)&p, sizeof (p)) == 0) - return (NULL); - kvm_proclist (cfd, pid, p, cnt); - if (!*cnt) { - zombproc = ksym_lookup("zombproc"); - if (kvm_read(cfd, zombproc, (char *)&p, sizeof (p)) == 0) - return (NULL); - kvm_proclist (cfd, pid, p, cnt); - } - return (&kp); -} - -/* - * try to do what kvm_getprocs in libkvm would do - */ -struct kinfo_proc * -kvm_getprocs (cfd, op, proc, cnt) -int cfd, op, *cnt; -CORE_ADDR proc; -{ - int mib[4], size; - - *cnt = 0; - /* assume it's a pid */ - if (devmem) { /* "live" kernel, use sysctl */ - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = (int)proc; - size = sizeof (kp); - if (sysctl (mib, 4, &kp, &size, NULL, 0) < 0) { - perror("sysctl"); - *cnt = 0; - return (NULL); - } - if (!size) - *cnt = 0; - else - *cnt = 1; - return (&kp); - } else - return (kvm_deadprocs (cfd, (int)proc, cnt)); -} - -static -physrd(cfd, addr, dat, len) -u_int addr; -char *dat; -{ - if (lseek(cfd, (off_t)addr, L_SET) == -1) - return (-1); - return (read(cfd, dat, len)); -} - -static CORE_ADDR -kvtophys (fd, addr) -CORE_ADDR addr; -{ - CORE_ADDR v; - unsigned int pte; - static CORE_ADDR PTD = -1; - CORE_ADDR current_ptd; -#ifdef DEBUG_KVTOPHYS - CORE_ADDR oldaddr = addr; -#endif - - /* - * If we're looking at the kernel stack, - * munge the address to refer to the user space mapping instead; - * that way we get the requested process's kstack, not the running one. - */ - /* - * this breaks xlating user addresses from a crash dump so only - * do it for a "live" kernel. - */ - if (devmem && addr >= kstack && addr < kstack + ctob(UPAGES)) - addr = (addr - kstack) + curpcb; - - /* - * We may no longer have a linear system page table... - * - * Here's the scoop. IdlePTD contains the physical address - * of a page table directory that always maps the kernel. - * IdlePTD is in memory that is mapped 1-to-1, so we can - * find it easily given its 'virtual' address from ksym_lookup(). - * For hysterical reasons, the value of IdlePTD is stored in sbr. - * - * To look up a kernel address, we first convert it to a 1st-level - * address and look it up in IdlePTD. This gives us the physical - * address of a page table page; we extract the 2nd-level part of - * VA and read the 2nd-level pte. Finally, we add the offset part - * of the VA into the physical address from the pte and return it. - * - * User addresses are a little more complicated. If we don't have - * a current PCB from read_pcb(), we use PTD, which is the (fixed) - * virtual address of the current ptd. Since it's NOT in 1-to-1 - * kernel space, we must look it up using IdlePTD. If we do have - * a pcb, we get the ptd from pcb_ptd. - */ - - if (INKERNEL(addr)) - current_ptd = sbr; - else if (found_pcb == 0) { - if (PTD == -1) - PTD = kvtophys(fd, ksym_lookup("PTD")); - current_ptd = PTD; - } else - current_ptd = pcb.pcb_cr3; - - /* - * Read the first-level page table (ptd). - */ - v = current_ptd + ((unsigned)addr >> PDRSHIFT) * sizeof pte; - if (physrd(fd, v, (char *)&pte, sizeof pte) < 0 || (pte&PG_V) == 0) - return (~0); - - /* - * Read the second-level page table. - */ - v = (pte&PG_FRAME) + ((addr >> PAGE_SHIFT)&(NPTEPG-1)) * sizeof pte; - if (physrd(fd, v, (char *) &pte, sizeof(pte)) < 0 || (pte&PG_V) == 0) - return (~0); - - addr = (pte & PG_FRAME) + (addr & PAGE_MASK); -#ifdef DEBUG_KVTOPHYS - printf("vtophys(%x) -> %x\n", oldaddr, addr); -#endif - return (addr); -} - -read_pcb (fd, uaddr) -CORE_ADDR uaddr; -{ - int i; - int *pcb_regs = (int *)&pcb; - int eip; - CORE_ADDR nuaddr = uaddr; - - /* need this for the `proc' command to work */ - if (INKERNEL(uaddr)) - nuaddr = kvtophys(fd, uaddr); - if (physrd(fd, nuaddr, (char *)&pcb, sizeof pcb) < 0) { - error("cannot read pcb at %#x\n", uaddr); - return (-1); - } - printf("current pcb at %#x\n", uaddr); - - /* - * get the register values out of the sys pcb and - * store them where `read_register' will find them. - */ - for (i = 0; i < 8; ++i) - supply_register(i, &pcb_regs[i+10]); - supply_register(8, &pcb_regs[8]); /* eip */ - supply_register(9, &pcb_regs[9]); /* eflags */ - for (i = 10; i < 13; ++i) /* cs, ss, ds */ - supply_register(i, &pcb_regs[i+9]); - supply_register(13, &pcb_regs[18]); /* es */ - for (i = 14; i < 16; ++i) /* fs, gs */ - supply_register(i, &pcb_regs[i+8]); - -#if 0 /* doesn't work ??? */ - /* Hmm... */ - if (target_read_memory(pcb_regs[5+10]+4, &eip, sizeof eip, 0)) - error("Cannot read PC."); - supply_register(8, &eip); /* eip */ -#endif - - /* XXX 80387 registers? */ -} - -/* - * read len bytes from kernel virtual address 'addr' into local - * buffer 'buf'. Return numbert of bytes if read ok, 0 otherwise. On read - * errors, portion of buffer not read is zeroed. - */ -kernel_core_file_hook(fd, addr, buf, len) - CORE_ADDR addr; - char *buf; - int len; -{ - int i; - CORE_ADDR paddr; - register char *cp; - int cc; - - cp = buf; - - while (len > 0) { - paddr = kvtophys(fd, addr); -#ifdef DEBUG_KCFH -if(!INKERNEL(addr)) -fprintf(stderr,"addr 0x%x, paddr 0x%x\n", addr, paddr); -#endif - if (paddr == ~0) { - bzero(buf, len); - break; - } - /* we can't read across a page boundary */ - i = min(len, PAGE_SIZE - (addr & PAGE_MASK)); - if ((cc = physrd(fd, paddr, cp, i)) <= 0) { - bzero(cp, len); - return (cp - buf); - } - cp += cc; - addr += cc; - len -= cc; - } - return (cp - buf); -} - -/* - * The following is FreeBSD-specific hackery to decode special frames - * and elide the assembly-language stub. This could be made faster by - * defining a frame_type field in the machine-dependent frame information, - * but we don't think that's too important right now. - */ -enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall }; - -CORE_ADDR -fbsd_kern_frame_saved_pc (fr) -struct frame_info *fr; -{ - struct minimal_symbol *sym; - CORE_ADDR this_saved_pc; - enum frametype frametype; - - this_saved_pc = read_memory_integer (fr->frame + 4, 4); - sym = lookup_minimal_symbol_by_pc (this_saved_pc); - frametype = tf_normal; - if (sym != NULL) { - if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) - frametype = tf_trap; - else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) - frametype = tf_interrupt; - else if (strcmp (SYMBOL_NAME(sym), "Xsyscall") == 0) - frametype = tf_syscall; - } - - switch (frametype) { - case tf_normal: - return (this_saved_pc); - -#define oEIP offsetof(struct trapframe, tf_eip) - - case tf_trap: - return (read_memory_integer (fr->frame + 8 + oEIP, 4)); - - case tf_interrupt: - return (read_memory_integer (fr->frame + 16 + oEIP, 4)); - - case tf_syscall: - return (read_memory_integer (fr->frame + 8 + oEIP, 4)); -#undef oEIP - } -} - -CORE_ADDR -fbsd_kern_frame_chain (fr) -struct frame_info *fr; -{ - struct minimal_symbol *sym; - CORE_ADDR this_saved_pc; - enum frametype frametype; - - this_saved_pc = read_memory_integer (fr->frame + 4, 4); - sym = lookup_minimal_symbol_by_pc (this_saved_pc); - frametype = tf_normal; - if (sym != NULL) { - if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) - frametype = tf_trap; - else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) - frametype = tf_interrupt; - else if (strcmp (SYMBOL_NAME(sym), "_Xsyscall") == 0) - frametype = tf_syscall; - } - - switch (frametype) { - case tf_normal: - return (read_memory_integer (fr->frame, 4)); - -#define oEBP offsetof(struct trapframe, tf_ebp) - - case tf_trap: - return (read_memory_integer (fr->frame + 8 + oEBP, 4)); - - case tf_interrupt: - return (read_memory_integer (fr->frame + 16 + oEBP, 4)); - - case tf_syscall: - return (read_memory_integer (fr->frame + 8 + oEBP, 4)); -#undef oEBP - } -} - -#endif /* KERNEL_DEBUG */ diff --git a/gnu/usr.bin/gdb/gdb/gdb-stabs.h b/gnu/usr.bin/gdb/gdb/gdb-stabs.h deleted file mode 100644 index 6c2a5f0..0000000 --- a/gnu/usr.bin/gdb/gdb/gdb-stabs.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Definitions for symbol-reading containing "stabs", for GDB. - Copyright 1992 Free Software Foundation, Inc. - Contributed by Cygnus Support. Written by John Gilmore. - -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. */ - -/* This file exists to hold the common definitions required of most of - the symbol-readers that end up using stabs. The common use of - these `symbol-type-specific' customizations of the generic data - structures makes the stabs-oriented symbol readers able to call - each others' functions as required. */ - -#if !defined (GDBSTABS_H) -#define GDBSTABS_H - -/* Offsets in the psymtab's section_offsets array for various kinds of - stabs symbols. Every psymtab built from stabs will have these offsets - filled in by these guidelines, so that when actually reading symbols, the - proper offset can simply be selected and added to the symbol value. */ - -#define SECT_OFF_TEXT 0 -#define SECT_OFF_DATA 1 -#define SECT_OFF_BSS 2 -#define SECT_OFF_RODATA 3 -#define SECT_OFF_MAX 4 /* Count of possible values */ - -/* The stab_section_info chain remembers info from the ELF symbol table, - while psymtabs are being built for the other symbol tables in the - objfile. It is destroyed at the complation of psymtab-reading. - Any info that was used from it has been copied into psymtabs. */ - -struct stab_section_info { - char *filename; - CORE_ADDR sections[SECT_OFF_MAX]; - struct stab_section_info *next; - int found; /* Count of times it's found in searching */ -}; - -/* Information is passed among various dbxread routines for accessing - symbol files. A pointer to this structure is kept in the sym_stab_info - field of the objfile struct. */ - -struct dbx_symfile_info { - asection *text_sect; /* Text section accessor */ - int symcount; /* How many symbols are there in the file */ - char *stringtab; /* The actual string table */ - int stringtab_size; /* Its size */ - file_ptr symtab_offset; /* Offset in file to symbol table */ - 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. */ -}; - -#define DBX_SYMFILE_INFO(o) ((struct dbx_symfile_info *)((o)->sym_stab_info)) -#define DBX_TEXT_SECT(o) (DBX_SYMFILE_INFO(o)->text_sect) -#define DBX_SYMCOUNT(o) (DBX_SYMFILE_INFO(o)->symcount) -#define DBX_STRINGTAB(o) (DBX_SYMFILE_INFO(o)->stringtab) -#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) - -#endif /* GDBSTABS_H */ diff --git a/gnu/usr.bin/gdb/gdb/gdb.1 b/gnu/usr.bin/gdb/gdb/gdb.1 deleted file mode 100644 index 13a6a77..0000000 --- a/gnu/usr.bin/gdb/gdb/gdb.1 +++ /dev/null @@ -1,390 +0,0 @@ -.\" Copyright (c) 1991 Free Software Foundation -.\" See section COPYING for conditions for redistribution -.\" $FreeBSD$ -.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools" -.SH NAME -gdb \- The GNU Debugger -.SH SYNOPSIS -.na -.TP -.B gdb -.RB "[\|" \-help "\|]" -.RB "[\|" \-nx "\|]" -.RB "[\|" \-q "\|]" -.RB "[\|" \-k "\|]" -.RB "[\|" \-w "\|]" -.RB "[\|" \-batch "\|]" -.RB "[\|" \-cd=\c -.I dir\c -\|] -.RB "[\|" \-f "\|]" -.RB "[\|" "\-b\ "\c -.IR bps "\|]" -.RB "[\|" "\-tty="\c -.IR dev "\|]" -.RB "[\|" "\-s "\c -.I symfile\c -\&\|] -.RB "[\|" "\-e "\c -.I prog\c -\&\|] -.RB "[\|" "\-se "\c -.I prog\c -\&\|] -.RB "[\|" "\-c "\c -.I core\c -\&\|] -.RB "[\|" "\-x "\c -.I cmds\c -\&\|] -.RB "[\|" "\-d "\c -.I dir\c -\&\|] -.RB "[\|" \c -.I prog\c -.RB "[\|" \c -.IR core \||\| procID\c -\&\|]\&\|] -.ad b -.SH DESCRIPTION -The purpose of a debugger such as GDB is to allow you to see what is -going on ``inside'' another program while it executes\(em\&or what another -program was doing at the moment it crashed. - -GDB can do four main kinds of things (plus other things in support of -these) to help you catch bugs in the act: - -.TP -\ \ \ \(bu -Start your program, specifying anything that might affect its behavior. - -.TP -\ \ \ \(bu -Make your program stop on specified conditions. - -.TP -\ \ \ \(bu -Examine what has happened, when your program has stopped. - -.TP -\ \ \ \(bu -Change things in your program, so you can experiment with correcting the -effects of one bug and go on to learn about another. -.PP - -You can use GDB to debug programs written in C, C++, and Modula-2. -Fortran support will be added when a GNU Fortran compiler is ready. - -GDB is invoked with the shell command \c -.B gdb\c -\&. Once started, it reads -commands from the terminal until you tell it to exit with the GDB -command \c -.B quit\c -\&. You can get online help from \c -.B gdb\c -\& itself -by using the command \c -.B help\c -\&. - -You can run \c -.B gdb\c -\& with no arguments or options; but the most -usual way to start GDB is with one argument or two, specifying an -executable program as the argument: -.sp -.br -gdb\ program -.br -.sp - -You can also start with both an executable program and a core file specified: -.sp -.br -gdb\ program\ core -.br -.sp - -You can, instead, specify a process ID as a second argument, if you want -to debug a running process: -.sp -.br -gdb\ program\ 1234 -.br -.sp - -would attach GDB to process \c -.B 1234\c -\& (unless you also have a file -named `\|\c -.B 1234\c -\&\|'; GDB does check for a core file first). - -Here are some of the most frequently needed GDB commands: -.TP -.B break \fR[\|\fIfile\fB:\fR\|]\fIfunction -\& -Set a breakpoint at \c -.I function\c -\& (in \c -.I file\c -\&). -.TP -.B run \fR[\|\fIarglist\fR\|] -Start your program (with \c -.I arglist\c -\&, if specified). -.TP -.B bt -Backtrace: display the program stack. -.TP -.BI print " expr"\c -\& -Display the value of an expression. -.TP -.B c -Continue running your program (after stopping, e.g. at a breakpoint). -.TP -.B next -Execute next program line (after stopping); step \c -.I over\c -\& any -function calls in the line. -.TP -.B step -Execute next program line (after stopping); step \c -.I into\c -\& any -function calls in the line. -.TP -.B help \fR[\|\fIname\fR\|] -Show information about GDB command \c -.I name\c -\&, or general information -about using GDB. -.TP -.B quit -Exit from GDB. -.PP -For full details on GDB, see \c -.I -Using GDB: A Guide to the GNU Source-Level Debugger\c -\&, by Richard M. Stallman and Roland H. Pesch. The same text is available online -as the \c -.B gdb\c -\& entry in the \c -.B info\c -\& program. -.SH OPTIONS -Any arguments other than options specify an executable -file and core file (or process ID); that is, the first argument -encountered with no -associated option flag is equivalent to a `\|\c -.B \-se\c -\&\|' option, and the -second, if any, is equivalent to a `\|\c -.B \-c\c -\&\|' option if it's the name of a file. Many options have -both long and short forms; both are shown here. The long forms are also -recognized if you truncate them, so long as enough of the option is -present to be unambiguous. (If you prefer, you can flag option -arguments with `\|\c -.B +\c -\&\|' rather than `\|\c -.B \-\c -\&\|', though we illustrate the -more usual convention.) - -All the options and command line arguments you give are processed -in sequential order. The order makes a difference when the -`\|\c -.B \-x\c -\&\|' option is used. - -.TP -.B \-help -.TP -.B \-h -List all options, with brief explanations. - -.TP -.BI "\-symbols=" "file"\c -.TP -.BI "\-s " "file"\c -\& -Read symbol table from file \c -.I file\c -\&. - -.TP -.BI "\-exec=" "file"\c -.TP -.BI "\-e " "file"\c -\& -Use file \c -.I file\c -\& as the executable file to execute when -appropriate, and for examining pure data in conjunction with a core -dump. - -.TP -.BI "\-se=" "file"\c -\& -Read symbol table from file \c -.I file\c -\& and use it as the executable -file. - -.TP -.BI "\-core=" "file"\c -.TP -.BI "\-c " "file"\c -\& -Use file \c -.I file\c -\& as a core dump to examine. - -.TP -.BI "\-command=" "file"\c -.TP -.BI "\-x " "file"\c -\& -Execute GDB commands from file \c -.I file\c -\&. - -.TP -.BI "\-directory=" "directory"\c -.TP -.BI "\-d " "directory"\c -\& -Add \c -.I directory\c -\& to the path to search for source files. -.PP - -.TP -.B \-nx -.TP -.B \-n -Do not execute commands from any `\|\c -.B .gdbinit\c -\&\|' initialization files. -Normally, the commands in these files are executed after all the -command options and arguments have been processed. - - -.TP -.B \-quiet -.TP -.B \-q -``Quiet''. Do not print the introductory and copyright messages. These -messages are also suppressed in batch mode. - -.TP -.B \-kernel -.TP -.B \-k -Puts GDB into kernel debugging mode. If no executable file is specified then -/kernel is used. If no core file is specified then /dev/mem is -used. Crash dumps can be examined by specifying both an executable and -a core file. - -.TP -.B \-wcore -.TP -.B \-w -This flag is only effective when debugging a "live" kernel. It makes the -core file (/dev/mem) writable so that kernel variables can be changed -during a debugging session. Use this with caution ! - -.TP -.B \-batch -Run in batch mode. Exit with status \c -.B 0\c -\& after processing all the command -files specified with `\|\c -.B \-x\c -\&\|' (and `\|\c -.B .gdbinit\c -\&\|', if not inhibited). -Exit with nonzero status if an error occurs in executing the GDB -commands in the command files. - -Batch mode may be useful for running GDB as a filter, for example to -download and run a program on another computer; in order to make this -more useful, the message -.sp -.br -Program\ exited\ normally. -.br -.sp - -(which is ordinarily issued whenever a program running under GDB control -terminates) is not issued when running in batch mode. - -.TP -.BI "\-cd=" "directory"\c -\& -Run GDB using \c -.I directory\c -\& as its working directory, -instead of the current directory. - -.TP -.B \-fullname -.TP -.B \-f -Emacs sets this option when it runs GDB as a subprocess. It tells GDB -to output the full file name and line number in a standard, -recognizable fashion each time a stack frame is displayed (which -includes each time the program stops). This recognizable format looks -like two `\|\c -.B \032\c -\&\|' characters, followed by the file name, line number -and character position separated by colons, and a newline. The -Emacs-to-GDB interface program uses the two `\|\c -.B \032\c -\&\|' characters as -a signal to display the source code for the frame. - -.TP -.BI "\-b " "bps"\c -\& -Set the line speed (baud rate or bits per second) of any serial -interface used by GDB for remote debugging. - -.TP -.BI "\-tty=" "device"\c -\& -Run using \c -.I device\c -\& for your program's standard input and output. -.PP - -.SH "SEE ALSO" -.RB "`\|" gdb "\|'" -entry in -.B info\c -\&; -.I -Using GDB: A Guide to the GNU Source-Level Debugger\c -, Richard M. Stallman and Roland H. Pesch, July 1991. -.SH COPYING -Copyright (c) 1991 Free Software Foundation, Inc. -.PP -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. -.PP -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. -.PP -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be included in -translations approved by the Free Software Foundation instead of in -the original English. diff --git a/gnu/usr.bin/gdb/gdb/gdbcmd.h b/gnu/usr.bin/gdb/gdb/gdbcmd.h deleted file mode 100644 index 88f323c..0000000 --- a/gnu/usr.bin/gdb/gdb/gdbcmd.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Header file for GDB-specific command-line stuff. - Copyright 1986, 1989, 1990, 1992 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#if !defined (GDBCMD_H) -#define GDBCMD_H 1 - -#include "command.h" - -/* Chain containing all defined commands. */ - -extern struct cmd_list_element *cmdlist; - -/* Chain containing all defined info subcommands. */ - -extern struct cmd_list_element *infolist; - -/* Chain containing all defined enable subcommands. */ - -extern struct cmd_list_element *enablelist; - -/* Chain containing all defined disable subcommands. */ - -extern struct cmd_list_element *disablelist; - -/* Chain containing all defined delete subcommands. */ - -extern struct cmd_list_element *deletelist; - -/* Chain containing all defined "enable breakpoint" subcommands. */ - -extern struct cmd_list_element *enablebreaklist; - -/* Chain containing all defined set subcommands */ - -extern struct cmd_list_element *setlist; - -/* Chain containing all defined unset subcommands */ - -extern struct cmd_list_element *unsetlist; - -/* Chain containing all defined show subcommands. */ - -extern struct cmd_list_element *showlist; - -/* Chain containing all defined \"set history\". */ - -extern struct cmd_list_element *sethistlist; - -/* Chain containing all defined \"show history\". */ - -extern struct cmd_list_element *showhistlist; - -/* Chain containing all defined \"unset history\". */ - -extern struct cmd_list_element *unsethistlist; - -/* Chain containing all defined maintenance subcommands. */ - -extern struct cmd_list_element *maintenancelist; - -/* Chain containing all defined "maintenance info" subcommands. */ - -extern struct cmd_list_element *maintenanceinfolist; - -/* Chain containing all defined "maintenance print" subcommands. */ - -extern struct cmd_list_element *maintenanceprintlist; - -extern struct cmd_list_element *setprintlist; - -extern struct cmd_list_element *showprintlist; - -extern struct cmd_list_element *setchecklist; - -extern struct cmd_list_element *showchecklist; - -extern void -execute_user_command PARAMS ((struct cmd_list_element *, char *)); - -extern void -execute_command PARAMS ((char *, int)); - -extern char **noop_completer PARAMS ((char *, char *)); - -extern char **filename_completer PARAMS ((char *, char *)); - -#endif /* !defined (GDBCMD_H) */ diff --git a/gnu/usr.bin/gdb/gdb/gdbcore.h b/gnu/usr.bin/gdb/gdb/gdbcore.h deleted file mode 100644 index 595e20c..0000000 --- a/gnu/usr.bin/gdb/gdb/gdbcore.h +++ /dev/null @@ -1,139 +0,0 @@ -/* Machine independent variables that describe the core file under GDB. - Copyright 1986, 1987, 1989, 1990, 1992 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. */ - -/* Interface routines for core, executable, etc. */ - -#if !defined (GDBCORE_H) -#define GDBCORE_H 1 - -#include "bfd.h" /* Binary File Description */ - -/* Return the name of the executable file as a string. - ERR nonzero means get error if there is none specified; - otherwise return 0 in that case. */ - -extern char * -get_exec_file PARAMS ((int err)); - -/* Nonzero if there is a core file. */ - -extern int -have_core_file_p PARAMS ((void)); - -/* Read "memory data" from whatever target or inferior we have. - Returns zero if successful, errno value if not. EIO is used - for address out of bounds. If breakpoints are inserted, returns - shadow contents, not the breakpoints themselves. From breakpoint.c. */ - -extern int -read_memory_nobpt PARAMS ((CORE_ADDR memaddr, char *myaddr, unsigned len)); - -/* Report a memory error with error(). */ - -extern void -memory_error PARAMS ((int status, CORE_ADDR memaddr)); - -/* Like target_read_memory, but report an error if can't read. */ - -extern void -read_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len)); - -/* Read an integer from debugged memory, given address and number of bytes. */ - -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)); - -/* This takes a char *, not void *. This is probably right, because - passing in an int * or whatever is wrong with respect to - byteswapping, alignment, different sizes for host vs. target types, - etc. */ - -extern void write_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len)); - -extern void generic_search PARAMS ((int len, char *data, char *mask, - CORE_ADDR startaddr, int increment, - CORE_ADDR lorange, CORE_ADDR hirange, - CORE_ADDR *addr_found, char *data_found)); - -/* Hook for `exec_file_command' command to call. */ - -extern void (*exec_file_display_hook) PARAMS ((char *filename)); - -extern void -specify_exec_file_hook PARAMS ((void (*hook) (char *filename))); - -/* Binary File Diddlers for the exec and core files */ -extern bfd *core_bfd; -extern bfd *exec_bfd; - -/* Whether to open exec and core files read-only or read-write. */ - -extern int write_files; - -extern void -core_file_command 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 int -xfer_core_file PARAMS ((CORE_ADDR memaddr, char *myaddr, int len)); - -extern void -fetch_core_registers PARAMS ((char *core_reg_sect, unsigned core_reg_size, - int which, unsigned int reg_addr)); - -extern void -registers_fetched PARAMS ((void)); - -#if !defined (KERNEL_U_ADDR) -extern CORE_ADDR kernel_u_addr; -#define KERNEL_U_ADDR kernel_u_addr -#endif - -/* The target vector for core files */ -extern struct target_ops core_ops; -#ifdef KERNEL_DEBUG -extern struct target_ops kcore_ops; -#endif - - /* target vector functions called directly from elsewhere */ -void -core_open PARAMS ((char *, int)); - -void -core_detach PARAMS ((char *, int)); - -/* The current default bfd target. */ -extern char *gnutarget; - -extern void set_gnutarget PARAMS ((char *)); - -#endif /* !defined (GDBCORE_H) */ diff --git a/gnu/usr.bin/gdb/gdb/gdbm.h b/gnu/usr.bin/gdb/gdb/gdbm.h deleted file mode 100644 index 5d244a3..0000000 --- a/gnu/usr.bin/gdb/gdb/gdbm.h +++ /dev/null @@ -1,91 +0,0 @@ -/* GNU DBM - DataBase Manager include file - Copyright 1989, 1991 Free Software Foundation, Inc. - Written by Philip A. Nelson. - -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. */ - -/* You may contact the author by: - e-mail: phil@wwu.edu - us-mail: Philip A. Nelson - Computer Science Department - Western Washington University - Bellingham, WA 98226 - phone: (206) 676-3035 - -*************************************************************************/ - -/* Parameters to gdbm_open for READERS, WRITERS, and WRITERS who - can create the database. */ -#define GDBM_READER 0 -#define GDBM_WRITER 1 -#define GDBM_WRCREAT 2 -#define GDBM_NEWDB 3 - -/* Parameters to gdbm_store for simple insertion or replacement. */ -#define GDBM_INSERT 0 -#define GDBM_REPLACE 1 - - -/* The data and key structure. This structure is defined for compatibility. */ -typedef struct { - char *dptr; - int dsize; - } datum; - - -/* The file information header. This is good enough for most applications. */ -typedef struct {int dummy[10];} *GDBM_FILE; - - -/* These are the routines! */ - -extern GDBM_FILE gdbm_open (); - -extern void gdbm_close (); - -extern datum gdbm_fetch (); - -extern int gdbm_store (); - -extern int gdbm_delete (); - -extern datum gdbm_firstkey (); - -extern datum gdbm_nextkey (); - -extern int gdbm_reorganize (); - - -/* gdbm sends back the following error codes in the variable gdbm_errno. */ -typedef enum { NO_ERROR, - MALLOC_ERROR, - BLOCK_SIZE_ERROR, - FILE_OPEN_ERROR, - FILE_WRITE_ERROR, - FILE_SEEK_ERROR, - FILE_READ_ERROR, - BAD_MAGIC_NUMBER, - EMPTY_DATABASE, - CANT_BE_READER, - CANT_BE_WRITER, - READER_CANT_RECOVER, - READER_CANT_DELETE, - READER_CANT_STORE, - READER_CANT_REORGANIZE, - UNKNOWN_UPDATE, - ITEM_NOT_FOUND, - REORGANIZE_FAILED, - CANNOT_REPLACE} - gdbm_error; diff --git a/gnu/usr.bin/gdb/gdb/gdbtypes.c b/gnu/usr.bin/gdb/gdb/gdbtypes.c deleted file mode 100644 index 36857be..0000000 --- a/gnu/usr.bin/gdb/gdb/gdbtypes.c +++ /dev/null @@ -1,1581 +0,0 @@ -/* Support routines for manipulating internal types for GDB. - Copyright (C) 1992 Free Software Foundation, Inc. - Contributed by Cygnus Support, using pieces from other GDB modules. - -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 "defs.h" -#include -#include "bfd.h" -#include "symtab.h" -#include "symfile.h" -#include "objfiles.h" -#include "gdbtypes.h" -#include "expression.h" -#include "language.h" -#include "target.h" -#include "value.h" -#include "demangle.h" -#include "complaints.h" - -/* These variables point to the objects - representing the predefined C data types. */ - -struct type *builtin_type_void; -struct type *builtin_type_char; -struct type *builtin_type_short; -struct type *builtin_type_int; -struct type *builtin_type_long; -struct type *builtin_type_long_long; -struct type *builtin_type_signed_char; -struct type *builtin_type_unsigned_char; -struct type *builtin_type_unsigned_short; -struct type *builtin_type_unsigned_int; -struct type *builtin_type_unsigned_long; -struct type *builtin_type_unsigned_long_long; -struct type *builtin_type_float; -struct type *builtin_type_double; -struct type *builtin_type_long_double; -struct type *builtin_type_complex; -struct type *builtin_type_double_complex; -struct type *builtin_type_string; - -/* Alloc a new type structure and fill it with some defaults. If - OBJFILE is non-NULL, then allocate the space for the type structure - in that objfile's type_obstack. */ - -struct type * -alloc_type (objfile) - struct objfile *objfile; -{ - register struct type *type; - - /* Alloc the structure and start off with all fields zeroed. */ - - if (objfile == NULL) - { - type = (struct type *) xmalloc (sizeof (struct type)); - } - else - { - type = (struct type *) obstack_alloc (&objfile -> type_obstack, - sizeof (struct type)); - } - memset ((char *) type, 0, sizeof (struct type)); - - /* Initialize the fields that might not be zero. */ - - TYPE_CODE (type) = TYPE_CODE_UNDEF; - TYPE_OBJFILE (type) = objfile; - TYPE_VPTR_FIELDNO (type) = -1; - - return (type); -} - -/* Lookup a pointer to a type TYPE. TYPEPTR, if nonzero, points - to a pointer to memory where the pointer type should be stored. - If *TYPEPTR is zero, update it to point to the pointer type we return. - We allocate new memory if needed. */ - -struct type * -make_pointer_type (type, typeptr) - struct type *type; - struct type **typeptr; -{ - register struct type *ntype; /* New type */ - struct objfile *objfile; - - 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 || *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; - } - - TYPE_TARGET_TYPE (ntype) = type; - TYPE_POINTER_TYPE (type) = ntype; - - /* FIXME! Assume the machine has only one representation for pointers! */ - - TYPE_LENGTH (ntype) = TARGET_PTR_BIT / TARGET_CHAR_BIT; - TYPE_CODE (ntype) = TYPE_CODE_PTR; - - /* pointers are unsigned */ - TYPE_FLAGS (ntype) |= TYPE_FLAG_UNSIGNED; - - if (!TYPE_POINTER_TYPE (type)) /* Remember it, if don't have one. */ - TYPE_POINTER_TYPE (type) = ntype; - - return ntype; -} - -/* Given a type TYPE, return a type of pointers to that type. - May need to construct such a type if this is the first use. */ - -struct type * -lookup_pointer_type (type) - struct type *type; -{ - return make_pointer_type (type, (struct type **)0); -} - -/* Lookup a C++ `reference' to a type TYPE. 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_reference_type (type, typeptr) - struct type *type; - struct type **typeptr; -{ - register struct type *ntype; /* New type */ - struct objfile *objfile; - - 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 || *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; - } - - TYPE_TARGET_TYPE (ntype) = type; - TYPE_REFERENCE_TYPE (type) = ntype; - - /* FIXME! Assume the machine has only one representation for references, - and that it matches the (only) representation for pointers! */ - - TYPE_LENGTH (ntype) = TARGET_PTR_BIT / TARGET_CHAR_BIT; - TYPE_CODE (ntype) = TYPE_CODE_REF; - - if (!TYPE_REFERENCE_TYPE (type)) /* Remember it, if don't have one. */ - TYPE_REFERENCE_TYPE (type) = ntype; - - return ntype; -} - -/* Same as above, but caller doesn't care about memory allocation details. */ - -struct type * -lookup_reference_type (type) - struct type *type; -{ - return make_reference_type (type, (struct type **)0); -} - -/* Lookup a function type that returns type TYPE. TYPEPTR, if nonzero, points - to a pointer to memory where the function type should be stored. - If *TYPEPTR is zero, update it to point to the function type we return. - We allocate new memory if needed. */ - -struct type * -make_function_type (type, typeptr) - struct type *type; - struct type **typeptr; -{ - register struct type *ntype; /* New type */ - struct objfile *objfile; - - ntype = TYPE_FUNCTION_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 || *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; - } - - TYPE_TARGET_TYPE (ntype) = type; - TYPE_FUNCTION_TYPE (type) = ntype; - - TYPE_LENGTH (ntype) = 1; - TYPE_CODE (ntype) = TYPE_CODE_FUNC; - - if (!TYPE_FUNCTION_TYPE (type)) /* Remember it, if don't have one. */ - TYPE_FUNCTION_TYPE (type) = ntype; - - return ntype; -} - - -/* Given a type TYPE, return a type of functions that return that type. - May need to construct such a type if this is the first use. */ - -struct type * -lookup_function_type (type) - struct type *type; -{ - return make_function_type (type, (struct type **)0); -} - -/* 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 - of the aggregate that the member belongs to. */ - -struct type * -lookup_member_type (type, domain) - struct type *type; - struct type *domain; -{ - register struct type *mtype; - - mtype = alloc_type (TYPE_OBJFILE (type)); - smash_to_member_type (mtype, domain, type); - return (mtype); -} - -/* Allocate a stub method whose return type is TYPE. - This apparently happens for speed of symbol reading, since parsing - out the arguments to the method is cpu-intensive, the way we are doing - it. So, we will fill in arguments later. - This always returns a fresh type. */ - -struct type * -allocate_stub_method (type) - struct type *type; -{ - struct type *mtype; - - mtype = alloc_type (TYPE_OBJFILE (type)); - TYPE_TARGET_TYPE (mtype) = type; - /* _DOMAIN_TYPE (mtype) = unknown yet */ - /* _ARG_TYPES (mtype) = unknown yet */ - TYPE_FLAGS (mtype) = TYPE_FLAG_STUB; - TYPE_CODE (mtype) = TYPE_CODE_METHOD; - TYPE_LENGTH (mtype) = 1; - return (mtype); -} - -/* Create a range type using either a blank type supplied in RESULT_TYPE, - or creating a new type, inheriting the objfile from INDEX_TYPE. - - Indices will be of type INDEX_TYPE, and will range from LOW_BOUND to - HIGH_BOUND, inclusive. - - FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make - sure it is TYPE_CODE_UNDEF before we bash it into a range type? */ - -struct type * -create_range_type (result_type, index_type, low_bound, high_bound) - struct type *result_type; - struct type *index_type; - int low_bound; - int high_bound; -{ - if (result_type == NULL) - { - result_type = alloc_type (TYPE_OBJFILE (index_type)); - } - TYPE_CODE (result_type) = TYPE_CODE_RANGE; - TYPE_TARGET_TYPE (result_type) = index_type; - TYPE_LENGTH (result_type) = TYPE_LENGTH (index_type); - TYPE_NFIELDS (result_type) = 2; - TYPE_FIELDS (result_type) = (struct field *) - TYPE_ALLOC (result_type, 2 * sizeof (struct field)); - memset (TYPE_FIELDS (result_type), 0, 2 * sizeof (struct field)); - TYPE_FIELD_BITPOS (result_type, 0) = low_bound; - TYPE_FIELD_BITPOS (result_type, 1) = high_bound; - TYPE_FIELD_TYPE (result_type, 0) = builtin_type_int; /* FIXME */ - TYPE_FIELD_TYPE (result_type, 1) = builtin_type_int; /* FIXME */ - - return (result_type); -} - -/* A lot of code assumes that the "index type" of an array/string/ - set/bitstring is specifically a range type, though in some languages - it can be any discrete type. */ - -struct type * -force_to_range_type (type) - struct type *type; -{ - switch (TYPE_CODE (type)) - { - case TYPE_CODE_RANGE: - return type; - - case TYPE_CODE_ENUM: - { - int low_bound = TYPE_FIELD_BITPOS (type, 0); - int high_bound = TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) - 1); - struct type *range_type = - create_range_type (NULL, type, low_bound, high_bound); - TYPE_NAME (range_type) = TYPE_NAME (range_type); - TYPE_DUMMY_RANGE (range_type) = 1; - return range_type; - } - case TYPE_CODE_BOOL: - { - struct type *range_type = create_range_type (NULL, type, 0, 1); - TYPE_NAME (range_type) = TYPE_NAME (range_type); - TYPE_DUMMY_RANGE (range_type) = 1; - return range_type; - } - case TYPE_CODE_CHAR: - { - struct type *range_type = create_range_type (NULL, type, 0, 255); - TYPE_NAME (range_type) = TYPE_NAME (range_type); - TYPE_DUMMY_RANGE (range_type) = 1; - return range_type; - } - default: - { - static struct complaint msg = - { "array index type must be a discrete type", 0, 0}; - complain (&msg); - - return create_range_type (NULL, builtin_type_int, 0, 0); - } - } -} - -/* Create an array type using either a blank type supplied in RESULT_TYPE, - or creating a new type, inheriting the objfile from RANGE_TYPE. - - Elements will be of type ELEMENT_TYPE, the indices will be of type - RANGE_TYPE. - - FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make - sure it is TYPE_CODE_UNDEF before we bash it into an array type? */ - -struct type * -create_array_type (result_type, element_type, range_type) - struct type *result_type; - struct type *element_type; - struct type *range_type; -{ - int low_bound; - int high_bound; - - range_type = force_to_range_type (range_type); - if (result_type == NULL) - { - result_type = alloc_type (TYPE_OBJFILE (range_type)); - } - TYPE_CODE (result_type) = TYPE_CODE_ARRAY; - TYPE_TARGET_TYPE (result_type) = element_type; - low_bound = TYPE_LOW_BOUND (range_type); - high_bound = TYPE_HIGH_BOUND (range_type); - TYPE_LENGTH (result_type) = - TYPE_LENGTH (element_type) * (high_bound - low_bound + 1); - TYPE_NFIELDS (result_type) = 1; - TYPE_FIELDS (result_type) = - (struct field *) TYPE_ALLOC (result_type, sizeof (struct field)); - memset (TYPE_FIELDS (result_type), 0, sizeof (struct field)); - TYPE_FIELD_TYPE (result_type, 0) = range_type; - TYPE_VPTR_FIELDNO (result_type) = -1; - - return (result_type); -} - -/* Create a string type using either a blank type supplied in RESULT_TYPE, - or creating a new type. String types are similar enough to array of - char types that we can use create_array_type to build the basic type - and then bash it into a string type. - - For fixed length strings, the range type contains 0 as the lower - bound and the length of the string minus one as the upper bound. - - FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make - sure it is TYPE_CODE_UNDEF before we bash it into a string type? */ - -struct type * -create_string_type (result_type, range_type) - struct type *result_type; - struct type *range_type; -{ - result_type = create_array_type (result_type, builtin_type_char, range_type); - TYPE_CODE (result_type) = TYPE_CODE_STRING; - return (result_type); -} - -struct type * -create_set_type (result_type, domain_type) - struct type *result_type; - struct type *domain_type; -{ - int low_bound, high_bound, bit_length; - if (result_type == NULL) - { - result_type = alloc_type (TYPE_OBJFILE (domain_type)); - } - domain_type = force_to_range_type (domain_type); - TYPE_CODE (result_type) = TYPE_CODE_SET; - TYPE_NFIELDS (result_type) = 1; - TYPE_FIELDS (result_type) = (struct field *) - TYPE_ALLOC (result_type, 1 * sizeof (struct field)); - memset (TYPE_FIELDS (result_type), 0, sizeof (struct field)); - TYPE_FIELD_TYPE (result_type, 0) = domain_type; - low_bound = TYPE_LOW_BOUND (domain_type); - high_bound = TYPE_HIGH_BOUND (domain_type); - bit_length = high_bound - low_bound + 1; - if (bit_length <= TARGET_CHAR_BIT) - TYPE_LENGTH (result_type) = 1; - else if (bit_length <= TARGET_SHORT_BIT) - TYPE_LENGTH (result_type) = TARGET_SHORT_BIT / TARGET_CHAR_BIT; - else - TYPE_LENGTH (result_type) - = ((bit_length + TARGET_INT_BIT - 1) / TARGET_INT_BIT) - * TARGET_CHAR_BIT; - return (result_type); -} - -/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE. - A MEMBER is a wierd thing -- it amounts to a typed offset into - a struct, e.g. "an int at offset 8". A MEMBER TYPE doesn't - include the offset (that's the value of the MEMBER itself), but does - include the structure type into which it points (for some reason). - - When "smashing" the type, we preserve the objfile that the - old type pointed to, since we aren't changing where the type is actually - allocated. */ - -void -smash_to_member_type (type, domain, to_type) - struct type *type; - struct type *domain; - struct type *to_type; -{ - struct objfile *objfile; - - objfile = TYPE_OBJFILE (type); - - memset ((char *) type, 0, sizeof (struct type)); - TYPE_OBJFILE (type) = objfile; - TYPE_TARGET_TYPE (type) = to_type; - TYPE_DOMAIN_TYPE (type) = domain; - TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */ - TYPE_CODE (type) = TYPE_CODE_MEMBER; -} - -/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE. - METHOD just means `function that gets an extra "this" argument'. - - When "smashing" the type, we preserve the objfile that the - old type pointed to, since we aren't changing where the type is actually - allocated. */ - -void -smash_to_method_type (type, domain, to_type, args) - struct type *type; - struct type *domain; - struct type *to_type; - struct type **args; -{ - struct objfile *objfile; - - objfile = TYPE_OBJFILE (type); - - memset ((char *) type, 0, sizeof (struct type)); - TYPE_OBJFILE (type) = objfile; - TYPE_TARGET_TYPE (type) = to_type; - TYPE_DOMAIN_TYPE (type) = domain; - TYPE_ARG_TYPES (type) = args; - TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */ - TYPE_CODE (type) = TYPE_CODE_METHOD; -} - -/* Return a typename for a struct/union/enum type without "struct ", - "union ", or "enum ". If the type has a NULL name, return NULL. */ - -char * -type_name_no_tag (type) - register const struct type *type; -{ - if (TYPE_TAG_NAME (type) != NULL) - return TYPE_TAG_NAME (type); - - /* Is there code which expects this to return the name if there is no - tag name? My guess is that this is mainly used for C++ in cases where - the two will always be the same. */ - return TYPE_NAME (type); -} - -/* Lookup a primitive type named NAME. - Return zero if NAME is not a primitive type.*/ - -struct type * -lookup_primitive_typename (name) - char *name; -{ - struct type ** const *p; - - for (p = current_language -> la_builtin_type_vector; *p != NULL; p++) - { - if (STREQ ((**p) -> name, name)) - { - return (**p); - } - } - return (NULL); -} - -/* Lookup a typedef or primitive type named NAME, - visible in lexical block BLOCK. - If NOERR is nonzero, return zero if NAME is not suitably defined. */ - -struct type * -lookup_typename (name, block, noerr) - char *name; - struct block *block; - int noerr; -{ - register struct symbol *sym; - register struct type *tmp; - - sym = lookup_symbol (name, block, VAR_NAMESPACE, 0, (struct symtab **) NULL); - if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF) - { - tmp = lookup_primitive_typename (name); - if (tmp) - { - return (tmp); - } - else if (!tmp && noerr) - { - return (NULL); - } - else - { - error ("No type named %s.", name); - } - } - return (SYMBOL_TYPE (sym)); -} - -struct type * -lookup_unsigned_typename (name) - char *name; -{ - char *uns = alloca (strlen (name) + 10); - - strcpy (uns, "unsigned "); - strcpy (uns + 9, name); - return (lookup_typename (uns, (struct block *) NULL, 0)); -} - -struct type * -lookup_signed_typename (name) - char *name; -{ - struct type *t; - char *uns = alloca (strlen (name) + 8); - - strcpy (uns, "signed "); - strcpy (uns + 7, name); - t = lookup_typename (uns, (struct block *) NULL, 1); - /* If we don't find "signed FOO" just try again with plain "FOO". */ - if (t != NULL) - return t; - return lookup_typename (name, (struct block *) NULL, 0); -} - -/* Lookup a structure type named "struct NAME", - visible in lexical block BLOCK. */ - -struct type * -lookup_struct (name, block) - char *name; - struct block *block; -{ - register struct symbol *sym; - - sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, - (struct symtab **) NULL); - - if (sym == NULL) - { - error ("No struct type named %s.", name); - } - if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT) - { - error ("This context has class, union or enum %s, not a struct.", name); - } - return (SYMBOL_TYPE (sym)); -} - -/* Lookup a union type named "union NAME", - visible in lexical block BLOCK. */ - -struct type * -lookup_union (name, block) - char *name; - struct block *block; -{ - register struct symbol *sym; - - 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)); -} - -/* Lookup an enum type named "enum NAME", - visible in lexical block BLOCK. */ - -struct type * -lookup_enum (name, block) - char *name; - struct block *block; -{ - register struct symbol *sym; - - sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, - (struct symtab **) NULL); - if (sym == NULL) - { - error ("No enum type named %s.", name); - } - if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM) - { - error ("This context has class, struct or union %s, not an enum.", name); - } - return (SYMBOL_TYPE (sym)); -} - -/* Lookup a template type named "template NAME", - visible in lexical block BLOCK. */ - -struct type * -lookup_template_type (name, type, block) - char *name; - struct type *type; - struct block *block; -{ - struct symbol *sym; - char *nam = (char*) alloca(strlen(name) + strlen(type->name) + 4); - strcpy (nam, name); - strcat (nam, "<"); - strcat (nam, type->name); - strcat (nam, " >"); /* FIXME, extra space still introduced in gcc? */ - - sym = lookup_symbol (nam, block, VAR_NAMESPACE, 0, (struct symtab **)NULL); - - if (sym == NULL) - { - error ("No template type named %s.", name); - } - if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT) - { - error ("This context has class, union or enum %s, not a struct.", name); - } - return (SYMBOL_TYPE (sym)); -} - -/* Given a type TYPE, lookup the type of the component of type named NAME. - - TYPE can be either a struct or union, or a pointer or reference to a struct or - union. If it is a pointer or reference, its target type is automatically used. - Thus '.' and '->' are interchangable, as specified for the definitions of the - expression element types STRUCTOP_STRUCT and STRUCTOP_PTR. - - If NOERR is nonzero, return zero if NAME is not suitably defined. - If NAME is the name of a baseclass type, return that type. */ - -struct type * -lookup_struct_elt_type (type, name, noerr) - struct type *type; - char *name; - int noerr; -{ - int i; - - while (TYPE_CODE (type) == TYPE_CODE_PTR || - TYPE_CODE (type) == TYPE_CODE_REF) - type = TYPE_TARGET_TYPE (type); - - if (TYPE_CODE (type) != TYPE_CODE_STRUCT && - TYPE_CODE (type) != TYPE_CODE_UNION) - { - target_terminal_ours (); - gdb_flush (gdb_stdout); - fprintf_unfiltered (gdb_stderr, "Type "); - type_print (type, "", gdb_stderr, -1); - error (" is not a structure or union type."); - } - - check_stub_type (type); - -#if 0 - /* FIXME: This change put in by Michael seems incorrect for the case where - the structure tag name is the same as the member name. I.E. when doing - "ptype bell->bar" for "struct foo { int bar; int foo; } bell;" - Disabled by fnf. */ - { - char *typename; - - typename = type_name_no_tag (type); - if (typename != NULL && STREQ (typename, name)) - return type; - } -#endif - - for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) - { - char *t_field_name = TYPE_FIELD_NAME (type, i); - - if (t_field_name && STREQ (t_field_name, name)) - { - return TYPE_FIELD_TYPE (type, i); - } - } - - /* OK, it's not in this class. Recursively check the baseclasses. */ - for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) - { - struct type *t; - - t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, noerr); - if (t != NULL) - { - return t; - } - } - - if (noerr) - { - return NULL; - } - - target_terminal_ours (); - gdb_flush (gdb_stdout); - fprintf_unfiltered (gdb_stderr, "Type "); - type_print (type, "", gdb_stderr, -1); - fprintf_unfiltered (gdb_stderr, " has no component named "); - fputs_filtered (name, gdb_stderr); - error ("."); - return (struct type *)-1; /* For lint */ -} - -/* If possible, make the vptr_fieldno and vptr_basetype fields of TYPE - valid. Callers should be aware that in some cases (for example, - the type or one of its baseclasses is a stub type and we are - debugging a .o file), this function will not be able to find the virtual - function table pointer, and vptr_fieldno will remain -1 and vptr_basetype - will remain NULL. */ - -void -fill_in_vptr_fieldno (type) - struct type *type; -{ - check_stub_type (type); - - if (TYPE_VPTR_FIELDNO (type) < 0) - { - int i; - - /* We must start at zero in case the first (and only) baseclass is - virtual (and hence we cannot share the table pointer). */ - for (i = 0; i < TYPE_N_BASECLASSES (type); i++) - { - fill_in_vptr_fieldno (TYPE_BASECLASS (type, i)); - if (TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i)) >= 0) - { - TYPE_VPTR_FIELDNO (type) - = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, i)); - TYPE_VPTR_BASETYPE (type) - = TYPE_VPTR_BASETYPE (TYPE_BASECLASS (type, i)); - break; - } - } - } -} - -/* 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 - we can find a full definition in some other file. If so, copy this - definition, so we can use it in future. There used to be a comment (but - not any code) that if we don't find a full definition, we'd set a flag - so we don't spend time in the future checking the same type. That would - be a mistake, though--we might load in more symbols which contain a - full definition for the type. - - This used to be coded as a macro, but I don't think it is called - often enough to merit such treatment. */ - -struct complaint stub_noname_complaint = - {"stub type has NULL name", 0, 0}; - -void -check_stub_type (type) - struct type *type; -{ - if (TYPE_FLAGS(type) & TYPE_FLAG_STUB) - { - char* name = type_name_no_tag (type); - /* FIXME: shouldn't we separately check the TYPE_NAME and the - TYPE_TAG_NAME, and look in STRUCT_NAMESPACE and/or VAR_NAMESPACE - as appropriate? (this code was written before TYPE_NAME and - TYPE_TAG_NAME were separate). */ - struct symbol *sym; - if (name == NULL) - { - complain (&stub_noname_complaint); - return; - } - sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, - (struct symtab **) NULL); - if (sym) - { - memcpy ((char *)type, - (char *)SYMBOL_TYPE(sym), - sizeof (struct type)); - } - } - - if (TYPE_FLAGS (type) & TYPE_FLAG_TARGET_STUB) - { - struct type *range_type; - - check_stub_type (TYPE_TARGET_TYPE (type)); - if (!(TYPE_FLAGS (TYPE_TARGET_TYPE (type)) & TYPE_FLAG_STUB) - && TYPE_CODE (type) == TYPE_CODE_ARRAY - && TYPE_NFIELDS (type) == 1 - && (TYPE_CODE (range_type = TYPE_FIELD_TYPE (type, 0)) - == TYPE_CODE_RANGE)) - { - /* Now recompute the length of the array type, based on its - number of elements and the target type's length. */ - TYPE_LENGTH (type) = - ((TYPE_FIELD_BITPOS (range_type, 1) - - TYPE_FIELD_BITPOS (range_type, 0) - + 1) - * TYPE_LENGTH (TYPE_TARGET_TYPE (type))); - TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB; - } - } -} - -/* Ugly hack to convert method stubs into method types. - - He ain't kiddin'. This demangles the name of the method into a string - including argument types, parses out each argument type, generates - a string casting a zero to that type, evaluates the string, and stuffs - the resulting type into an argtype vector!!! Then it knows the type - of the whole function (including argument types for overloading), - which info used to be in the stab's but was removed to hack back - the space required for them. */ - -void -check_stub_method (type, i, j) - struct type *type; - int i; - int j; -{ - struct fn_field *f; - char *mangled_name = gdb_mangle_name (type, i, j); - char *demangled_name = cplus_demangle (mangled_name, - DMGL_PARAMS | DMGL_ANSI); - char *argtypetext, *p; - int depth = 0, argcount = 1; - struct type **argtypes; - struct type *mtype; - - if (demangled_name == NULL) - { - error ("Internal: Cannot demangle mangled name `%s'.", mangled_name); - } - - /* Now, read in the parameters that define this type. */ - argtypetext = strchr (demangled_name, '(') + 1; - p = argtypetext; - while (*p) - { - if (*p == '(') - { - depth += 1; - } - else if (*p == ')') - { - depth -= 1; - } - else if (*p == ',' && depth == 0) - { - argcount += 1; - } - - p += 1; - } - - /* We need two more slots: one for the THIS pointer, and one for the - NULL [...] or void [end of arglist]. */ - - argtypes = (struct type **) - TYPE_ALLOC (type, (argcount + 2) * sizeof (struct type *)); - p = argtypetext; - /* FIXME: This is wrong for static member functions. */ - argtypes[0] = lookup_pointer_type (type); - argcount = 1; - - if (*p != ')') /* () means no args, skip while */ - { - depth = 0; - while (*p) - { - if (depth <= 0 && (*p == ',' || *p == ')')) - { - /* Avoid parsing of ellipsis, they will be handled below. */ - if (strncmp (argtypetext, "...", p - argtypetext) != 0) - { - argtypes[argcount] = - parse_and_eval_type (argtypetext, p - argtypetext); - argcount += 1; - } - argtypetext = p + 1; - } - - if (*p == '(') - { - depth += 1; - } - else if (*p == ')') - { - depth -= 1; - } - - p += 1; - } - } - - if (p[-2] != '.') /* Not '...' */ - { - argtypes[argcount] = builtin_type_void; /* List terminator */ - } - else - { - argtypes[argcount] = NULL; /* Ellist terminator */ - } - - free (demangled_name); - - f = TYPE_FN_FIELDLIST1 (type, i); - TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name; - - /* Now update the old "stub" type into a real type. */ - mtype = TYPE_FN_FIELD_TYPE (f, j); - TYPE_DOMAIN_TYPE (mtype) = type; - TYPE_ARG_TYPES (mtype) = argtypes; - TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB; - TYPE_FN_FIELD_STUB (f, j) = 0; -} - -const struct cplus_struct_type cplus_struct_default; - -void -allocate_cplus_struct_type (type) - struct type *type; -{ - if (!HAVE_CPLUS_STRUCT (type)) - { - TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *) - TYPE_ALLOC (type, sizeof (struct cplus_struct_type)); - *(TYPE_CPLUS_SPECIFIC(type)) = cplus_struct_default; - } -} - -/* Helper function to initialize the standard scalar types. - - If NAME is non-NULL and OBJFILE is non-NULL, then we make a copy - of the string pointed to by name in the type_obstack for that objfile, - and initialize the type name to that copy. There are places (mipsread.c - in particular, where init_type is called with a NULL value for NAME). */ - -struct type * -init_type (code, length, flags, name, objfile) - enum type_code code; - int length; - int flags; - char *name; - struct objfile *objfile; -{ - register struct type *type; - - type = alloc_type (objfile); - TYPE_CODE (type) = code; - TYPE_LENGTH (type) = length; - TYPE_FLAGS (type) |= flags; - if ((name != NULL) && (objfile != NULL)) - { - TYPE_NAME (type) = - obsavestring (name, strlen (name), &objfile -> type_obstack); - } - else - { - TYPE_NAME (type) = name; - } - - /* C++ fancies. */ - - if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) - { - INIT_CPLUS_SPECIFIC (type); - } - return (type); -} - -/* Look up a fundamental type for the specified objfile. - May need to construct such a type if this is the first use. - - Some object file formats (ELF, COFF, etc) do not define fundamental - types such as "int" or "double". Others (stabs for example), do - define fundamental types. - - For the formats which don't provide fundamental types, gdb can create - such types, using defaults reasonable for the current language and - the current target machine. - - NOTE: This routine is obsolescent. Each debugging format reader - should manage it's own fundamental types, either creating them from - suitable defaults or reading them from the debugging information, - whichever is appropriate. The DWARF reader has already been - fixed to do this. Once the other readers are fixed, this routine - will go away. Also note that fundamental types should be managed - on a compilation unit basis in a multi-language environment, not - on a linkage unit basis as is done here. */ - - -struct type * -lookup_fundamental_type (objfile, typeid) - struct objfile *objfile; - int typeid; -{ - register struct type **typep; - register int nbytes; - - if (typeid < 0 || typeid >= FT_NUM_MEMBERS) - { - error ("internal error - invalid fundamental type id %d", typeid); - } - - /* If this is the first time we need a fundamental type for this objfile - then we need to initialize the vector of type pointers. */ - - if (objfile -> fundamental_types == NULL) - { - nbytes = FT_NUM_MEMBERS * sizeof (struct type *); - objfile -> fundamental_types = (struct type **) - obstack_alloc (&objfile -> type_obstack, nbytes); - memset ((char *) objfile -> fundamental_types, 0, nbytes); - } - - /* Look for this particular type in the fundamental type vector. If one is - not found, create and install one appropriate for the current language. */ - - typep = objfile -> fundamental_types + typeid; - if (*typep == NULL) - { - *typep = create_fundamental_type (objfile, typeid); - } - - return (*typep); -} - -int -can_dereference (t) - struct type *t; -{ - /* FIXME: Should we return true for references as well as pointers? */ - return - (t != NULL - && TYPE_CODE (t) == TYPE_CODE_PTR - && TYPE_CODE (TYPE_TARGET_TYPE (t)) != TYPE_CODE_VOID); -} - -#if MAINTENANCE_CMDS - -static void -print_bit_vector (bits, nbits) - B_TYPE *bits; - int nbits; -{ - int bitno; - - for (bitno = 0; bitno < nbits; bitno++) - { - if ((bitno % 8) == 0) - { - puts_filtered (" "); - } - if (B_TST (bits, bitno)) - { - printf_filtered ("1"); - } - else - { - printf_filtered ("0"); - } - } -} - -/* The args list is a strange beast. It is either terminated by a NULL - pointer for varargs functions, or by a pointer to a TYPE_CODE_VOID - type for normal fixed argcount functions. (FIXME someday) - Also note the first arg should be the "this" pointer, we may not want to - include it since we may get into a infinitely recursive situation. */ - -static void -print_arg_types (args, spaces) - struct type **args; - int spaces; -{ - if (args != NULL) - { - while (*args != NULL) - { - recursive_dump_type (*args, spaces + 2); - if ((*args++) -> code == TYPE_CODE_VOID) - { - break; - } - } - } -} - -static void -dump_fn_fieldlists (type, spaces) - struct type *type; - int spaces; -{ - int method_idx; - int overload_idx; - struct fn_field *f; - - printfi_filtered (spaces, "fn_fieldlists "); - gdb_print_address (TYPE_FN_FIELDLISTS (type), gdb_stdout); - printf_filtered ("\n"); - for (method_idx = 0; method_idx < TYPE_NFN_FIELDS (type); method_idx++) - { - f = TYPE_FN_FIELDLIST1 (type, method_idx); - printfi_filtered (spaces + 2, "[%d] name '%s' (", - method_idx, - TYPE_FN_FIELDLIST_NAME (type, method_idx)); - gdb_print_address (TYPE_FN_FIELDLIST_NAME (type, method_idx), - gdb_stdout); - printf_filtered (") length %d\n", - TYPE_FN_FIELDLIST_LENGTH (type, method_idx)); - for (overload_idx = 0; - overload_idx < TYPE_FN_FIELDLIST_LENGTH (type, method_idx); - overload_idx++) - { - printfi_filtered (spaces + 4, "[%d] physname '%s' (", - overload_idx, - TYPE_FN_FIELD_PHYSNAME (f, overload_idx)); - gdb_print_address (TYPE_FN_FIELD_PHYSNAME (f, overload_idx), - gdb_stdout); - printf_filtered (")\n"); - printfi_filtered (spaces + 8, "type "); - gdb_print_address (TYPE_FN_FIELD_TYPE (f, overload_idx), gdb_stdout); - printf_filtered ("\n"); - - recursive_dump_type (TYPE_FN_FIELD_TYPE (f, overload_idx), - spaces + 8 + 2); - - printfi_filtered (spaces + 8, "args "); - gdb_print_address (TYPE_FN_FIELD_ARGS (f, overload_idx), gdb_stdout); - printf_filtered ("\n"); - - print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx), spaces); - printfi_filtered (spaces + 8, "fcontext "); - gdb_print_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx), - gdb_stdout); - printf_filtered ("\n"); - - printfi_filtered (spaces + 8, "is_const %d\n", - TYPE_FN_FIELD_CONST (f, overload_idx)); - printfi_filtered (spaces + 8, "is_volatile %d\n", - TYPE_FN_FIELD_VOLATILE (f, overload_idx)); - printfi_filtered (spaces + 8, "is_private %d\n", - TYPE_FN_FIELD_PRIVATE (f, overload_idx)); - printfi_filtered (spaces + 8, "is_protected %d\n", - TYPE_FN_FIELD_PROTECTED (f, overload_idx)); - printfi_filtered (spaces + 8, "is_stub %d\n", - TYPE_FN_FIELD_STUB (f, overload_idx)); - printfi_filtered (spaces + 8, "voffset %u\n", - TYPE_FN_FIELD_VOFFSET (f, overload_idx)); - } - } -} - -static void -print_cplus_stuff (type, spaces) - struct type *type; - int spaces; -{ - printfi_filtered (spaces, "n_baseclasses %d\n", - TYPE_N_BASECLASSES (type)); - printfi_filtered (spaces, "nfn_fields %d\n", - TYPE_NFN_FIELDS (type)); - printfi_filtered (spaces, "nfn_fields_total %d\n", - TYPE_NFN_FIELDS_TOTAL (type)); - if (TYPE_N_BASECLASSES (type) > 0) - { - printfi_filtered (spaces, "virtual_field_bits (%d bits at *", - TYPE_N_BASECLASSES (type)); - gdb_print_address (TYPE_FIELD_VIRTUAL_BITS (type), gdb_stdout); - printf_filtered (")"); - - print_bit_vector (TYPE_FIELD_VIRTUAL_BITS (type), - TYPE_N_BASECLASSES (type)); - puts_filtered ("\n"); - } - if (TYPE_NFIELDS (type) > 0) - { - if (TYPE_FIELD_PRIVATE_BITS (type) != NULL) - { - printfi_filtered (spaces, "private_field_bits (%d bits at *", - TYPE_NFIELDS (type)); - gdb_print_address (TYPE_FIELD_PRIVATE_BITS (type), gdb_stdout); - printf_filtered (")"); - print_bit_vector (TYPE_FIELD_PRIVATE_BITS (type), - TYPE_NFIELDS (type)); - puts_filtered ("\n"); - } - if (TYPE_FIELD_PROTECTED_BITS (type) != NULL) - { - printfi_filtered (spaces, "protected_field_bits (%d bits at *", - TYPE_NFIELDS (type)); - gdb_print_address (TYPE_FIELD_PROTECTED_BITS (type), gdb_stdout); - printf_filtered (")"); - print_bit_vector (TYPE_FIELD_PROTECTED_BITS (type), - TYPE_NFIELDS (type)); - puts_filtered ("\n"); - } - } - if (TYPE_NFN_FIELDS (type) > 0) - { - dump_fn_fieldlists (type, spaces); - } -} - -void -recursive_dump_type (type, spaces) - struct type *type; - int spaces; -{ - int idx; - - printfi_filtered (spaces, "type node "); - gdb_print_address (type, gdb_stdout); - printf_filtered ("\n"); - printfi_filtered (spaces, "name '%s' (", - TYPE_NAME (type) ? TYPE_NAME (type) : ""); - gdb_print_address (TYPE_NAME (type), gdb_stdout); - printf_filtered (")\n"); - if (TYPE_TAG_NAME (type) != NULL) - { - printfi_filtered (spaces, "tagname '%s' (", - TYPE_TAG_NAME (type)); - gdb_print_address (TYPE_TAG_NAME (type), gdb_stdout); - printf_filtered (")\n"); - } - printfi_filtered (spaces, "code 0x%x ", TYPE_CODE (type)); - switch (TYPE_CODE (type)) - { - case TYPE_CODE_UNDEF: - printf_filtered ("(TYPE_CODE_UNDEF)"); - break; - case TYPE_CODE_PTR: - printf_filtered ("(TYPE_CODE_PTR)"); - break; - case TYPE_CODE_ARRAY: - printf_filtered ("(TYPE_CODE_ARRAY)"); - break; - case TYPE_CODE_STRUCT: - printf_filtered ("(TYPE_CODE_STRUCT)"); - break; - case TYPE_CODE_UNION: - printf_filtered ("(TYPE_CODE_UNION)"); - break; - case TYPE_CODE_ENUM: - printf_filtered ("(TYPE_CODE_ENUM)"); - break; - case TYPE_CODE_FUNC: - printf_filtered ("(TYPE_CODE_FUNC)"); - break; - case TYPE_CODE_INT: - printf_filtered ("(TYPE_CODE_INT)"); - break; - case TYPE_CODE_FLT: - printf_filtered ("(TYPE_CODE_FLT)"); - break; - case TYPE_CODE_VOID: - printf_filtered ("(TYPE_CODE_VOID)"); - break; - case TYPE_CODE_SET: - printf_filtered ("(TYPE_CODE_SET)"); - break; - case TYPE_CODE_RANGE: - printf_filtered ("(TYPE_CODE_RANGE)"); - break; - case TYPE_CODE_STRING: - printf_filtered ("(TYPE_CODE_STRING)"); - break; - case TYPE_CODE_ERROR: - printf_filtered ("(TYPE_CODE_ERROR)"); - break; - case TYPE_CODE_MEMBER: - printf_filtered ("(TYPE_CODE_MEMBER)"); - break; - case TYPE_CODE_METHOD: - printf_filtered ("(TYPE_CODE_METHOD)"); - break; - case TYPE_CODE_REF: - printf_filtered ("(TYPE_CODE_REF)"); - break; - case TYPE_CODE_CHAR: - printf_filtered ("(TYPE_CODE_CHAR)"); - break; - case TYPE_CODE_BOOL: - printf_filtered ("(TYPE_CODE_BOOL)"); - break; - default: - printf_filtered ("(UNKNOWN TYPE CODE)"); - break; - } - puts_filtered ("\n"); - printfi_filtered (spaces, "length %d\n", TYPE_LENGTH (type)); - printfi_filtered (spaces, "objfile "); - gdb_print_address (TYPE_OBJFILE (type), gdb_stdout); - printf_filtered ("\n"); - printfi_filtered (spaces, "target_type "); - gdb_print_address (TYPE_TARGET_TYPE (type), gdb_stdout); - printf_filtered ("\n"); - if (TYPE_TARGET_TYPE (type) != NULL) - { - recursive_dump_type (TYPE_TARGET_TYPE (type), spaces + 2); - } - printfi_filtered (spaces, "pointer_type "); - gdb_print_address (TYPE_POINTER_TYPE (type), gdb_stdout); - printf_filtered ("\n"); - printfi_filtered (spaces, "reference_type "); - gdb_print_address (TYPE_REFERENCE_TYPE (type), gdb_stdout); - printf_filtered ("\n"); - printfi_filtered (spaces, "function_type "); - gdb_print_address (TYPE_FUNCTION_TYPE (type), gdb_stdout); - printf_filtered ("\n"); - printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type)); - if (TYPE_FLAGS (type) & TYPE_FLAG_UNSIGNED) - { - puts_filtered (" TYPE_FLAG_UNSIGNED"); - } - if (TYPE_FLAGS (type) & TYPE_FLAG_STUB) - { - puts_filtered (" TYPE_FLAG_STUB"); - } - puts_filtered ("\n"); - printfi_filtered (spaces, "nfields %d ", TYPE_NFIELDS (type)); - gdb_print_address (TYPE_FIELDS (type), gdb_stdout); - puts_filtered ("\n"); - for (idx = 0; idx < TYPE_NFIELDS (type); idx++) - { - printfi_filtered (spaces + 2, - "[%d] bitpos %d bitsize %d type ", - idx, TYPE_FIELD_BITPOS (type, idx), - TYPE_FIELD_BITSIZE (type, idx)); - gdb_print_address (TYPE_FIELD_TYPE (type, idx), gdb_stdout); - printf_filtered (" name '%s' (", - TYPE_FIELD_NAME (type, idx) != NULL - ? TYPE_FIELD_NAME (type, idx) - : ""); - gdb_print_address (TYPE_FIELD_NAME (type, idx), gdb_stdout); - printf_filtered (")\n"); - if (TYPE_FIELD_TYPE (type, idx) != NULL) - { - recursive_dump_type (TYPE_FIELD_TYPE (type, idx), spaces + 4); - } - } - printfi_filtered (spaces, "vptr_basetype "); - gdb_print_address (TYPE_VPTR_BASETYPE (type), gdb_stdout); - puts_filtered ("\n"); - if (TYPE_VPTR_BASETYPE (type) != NULL) - { - recursive_dump_type (TYPE_VPTR_BASETYPE (type), spaces + 2); - } - printfi_filtered (spaces, "vptr_fieldno %d\n", TYPE_VPTR_FIELDNO (type)); - switch (TYPE_CODE (type)) - { - case TYPE_CODE_METHOD: - case TYPE_CODE_FUNC: - printfi_filtered (spaces, "arg_types "); - gdb_print_address (TYPE_ARG_TYPES (type), gdb_stdout); - puts_filtered ("\n"); - print_arg_types (TYPE_ARG_TYPES (type), spaces); - break; - - case TYPE_CODE_STRUCT: - printfi_filtered (spaces, "cplus_stuff "); - gdb_print_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout); - puts_filtered ("\n"); - print_cplus_stuff (type, spaces); - break; - - default: - /* We have to pick one of the union types to be able print and test - the value. Pick cplus_struct_type, even though we know it isn't - any particular one. */ - printfi_filtered (spaces, "type_specific "); - gdb_print_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout); - if (TYPE_CPLUS_SPECIFIC (type) != NULL) - { - printf_filtered (" (unknown data form)"); - } - printf_filtered ("\n"); - break; - - } -} - -#endif /* MAINTENANCE_CMDS */ - -void -_initialize_gdbtypes () -{ - builtin_type_void = - init_type (TYPE_CODE_VOID, 1, - 0, - "void", (struct objfile *) NULL); - builtin_type_char = - init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, - "char", (struct objfile *) NULL); - builtin_type_signed_char = - init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, - "signed char", (struct objfile *) NULL); - builtin_type_unsigned_char = - init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "unsigned char", (struct objfile *) NULL); - builtin_type_short = - init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT, - 0, - "short", (struct objfile *) NULL); - builtin_type_unsigned_short = - init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "unsigned short", (struct objfile *) NULL); - builtin_type_int = - init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, - "int", (struct objfile *) NULL); - builtin_type_unsigned_int = - init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "unsigned int", (struct objfile *) NULL); - builtin_type_long = - init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, - 0, - "long", (struct objfile *) NULL); - builtin_type_unsigned_long = - init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "unsigned long", (struct objfile *) NULL); - builtin_type_long_long = - init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, - 0, - "long long", (struct objfile *) NULL); - builtin_type_unsigned_long_long = - init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "unsigned long long", (struct objfile *) NULL); - builtin_type_float = - init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT, - 0, - "float", (struct objfile *) NULL); - builtin_type_double = - init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, - 0, - "double", (struct objfile *) NULL); - builtin_type_long_double = - init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, - 0, - "long double", (struct objfile *) NULL); - builtin_type_complex = - init_type (TYPE_CODE_FLT, TARGET_COMPLEX_BIT / TARGET_CHAR_BIT, - 0, - "complex", (struct objfile *) NULL); - builtin_type_double_complex = - init_type (TYPE_CODE_FLT, TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT, - 0, - "double complex", (struct objfile *) NULL); - builtin_type_string = - init_type (TYPE_CODE_STRING, TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, - "string", (struct objfile *) NULL); -} diff --git a/gnu/usr.bin/gdb/gdb/gdbtypes.h b/gnu/usr.bin/gdb/gdb/gdbtypes.h deleted file mode 100644 index 8ba6bfa..0000000 --- a/gnu/usr.bin/gdb/gdb/gdbtypes.h +++ /dev/null @@ -1,735 +0,0 @@ -/* Internal type definitions for GDB. - Copyright (C) 1992 Free Software Foundation, Inc. - Contributed by Cygnus Support, using pieces from other GDB modules. - -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 (GDBTYPES_H) -#define GDBTYPES_H 1 - -/* Codes for `fundamental types'. This is a monstrosity based on the - bogus notion that there are certain compiler-independent - `fundamental types'. None of these is well-defined (how big is - FT_SHORT? Does it depend on the language? How does the - language-specific code know which type to correlate to FT_SHORT?) */ - -#define FT_VOID 0 -#define FT_BOOLEAN 1 -#define FT_CHAR 2 -#define FT_SIGNED_CHAR 3 -#define FT_UNSIGNED_CHAR 4 -#define FT_SHORT 5 -#define FT_SIGNED_SHORT 6 -#define FT_UNSIGNED_SHORT 7 -#define FT_INTEGER 8 -#define FT_SIGNED_INTEGER 9 -#define FT_UNSIGNED_INTEGER 10 -#define FT_LONG 11 -#define FT_SIGNED_LONG 12 -#define FT_UNSIGNED_LONG 13 -#define FT_LONG_LONG 14 -#define FT_SIGNED_LONG_LONG 15 -#define FT_UNSIGNED_LONG_LONG 16 -#define FT_FLOAT 17 -#define FT_DBL_PREC_FLOAT 18 -#define FT_EXT_PREC_FLOAT 19 -#define FT_COMPLEX 20 -#define FT_DBL_PREC_COMPLEX 21 -#define FT_EXT_PREC_COMPLEX 22 -#define FT_STRING 23 -#define FT_FIXED_DECIMAL 24 -#define FT_FLOAT_DECIMAL 25 -#define FT_BYTE 26 -#define FT_UNSIGNED_BYTE 27 - -#define FT_NUM_MEMBERS 28 /* Highest FT_* above, plus one. */ - -/* Some macros for char-based bitfields. */ - -#define B_SET(a,x) ((a)[(x)>>3] |= (1 << ((x)&7))) -#define B_CLR(a,x) ((a)[(x)>>3] &= ~(1 << ((x)&7))) -#define B_TST(a,x) ((a)[(x)>>3] & (1 << ((x)&7))) -#define B_TYPE unsigned char -#define B_BYTES(x) ( 1 + ((x)>>3) ) -#define B_CLRALL(a,x) memset ((a), 0, B_BYTES(x)) - -/* Different kinds of data types are distinguished by the `code' field. */ - -enum type_code -{ - TYPE_CODE_UNDEF, /* Not used; catches errors */ - TYPE_CODE_PTR, /* Pointer type */ - TYPE_CODE_ARRAY, /* Array type with lower & upper bounds. */ - TYPE_CODE_STRUCT, /* C struct or Pascal record */ - TYPE_CODE_UNION, /* C union or Pascal variant part */ - TYPE_CODE_ENUM, /* Enumeration type */ - TYPE_CODE_FUNC, /* Function type */ - TYPE_CODE_INT, /* Integer type */ - - /* Floating type. This is *NOT* a complex type. Complex types, when - we have them, will have their own type code (or TYPE_CODE_ERROR if - we can parse a complex type but not manipulate it). There are parts - of GDB which bogusly assume that TYPE_CODE_FLT can mean complex. */ - TYPE_CODE_FLT, - - /* Void type. The length field specifies the length (probably always - one) which is used in pointer arithmetic involving pointers to - this type, but actually dereferencing such a pointer is invalid; - a void type has no length and no actual representation in memory - or registers. A pointer to a void type is a generic pointer. */ - TYPE_CODE_VOID, - - TYPE_CODE_SET, /* Pascal sets */ - TYPE_CODE_RANGE, /* Range (integers within spec'd bounds) */ - - /* A string type which is like an array of character but prints - differently (at least for CHILL). It does not contain a length - field as Pascal strings (for many Pascals, anyway) do; if we want - to deal with such strings, we should use a new type code. */ - TYPE_CODE_STRING, - - /* String of bits; like TYPE_CODE_SET but prints differently (at least - for CHILL). */ - TYPE_CODE_BITSTRING, - - /* Unknown type. The length field is valid if we were able to - deduce that much about the type, or 0 if we don't even know that. */ - TYPE_CODE_ERROR, - - /* C++ */ - TYPE_CODE_MEMBER, /* Member type */ - TYPE_CODE_METHOD, /* Method type */ - TYPE_CODE_REF, /* C++ Reference types */ - - TYPE_CODE_CHAR, /* *real* character type */ - - /* Boolean type. 0 is false, 1 is true, and other values are non-boolean - (e.g. FORTRAN "logical" used as unsigned int). */ - TYPE_CODE_BOOL -}; - -/* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an - alias for TYPE_CODE_STRUCT. This is for DWARF, which has a distinct - "class" attribute. Perhaps we should actually have a separate TYPE_CODE - so that we can print "class" or "struct" depending on what the debug - info said. It's not clear we should bother. */ - -#define TYPE_CODE_CLASS TYPE_CODE_STRUCT - -/* 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. */ - -#define TYPE_FLAG_UNSIGNED (1 << 0) - -/* 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 *)). */ - -#define TYPE_FLAG_STUB (1 << 2) - -/* The target type of this type is a stub type, and this type needs to - be updated if it gets un-stubbed in check_stub_type. Currently only - used for arrays, in which TYPE_LENGTH of the array gets set based - on the TYPE_LENGTH of the target type. */ - -#define TYPE_FLAG_TARGET_STUB (1 << 3) - -struct type -{ - - /* Code for kind of type */ - - enum type_code code; - - /* Name of this type, or NULL if none. - - This is used for printing only, except by poorly designed C++ code. - For looking up a name, look for a symbol in the VAR_NAMESPACE. */ - - char *name; - - /* Tag name for this type, or NULL if none. This means that the - name of the type consists of a keyword followed by the tag name. - Which keyword is determined by the type code ("struct" for - TYPE_CODE_STRUCT, etc.). As far as I know C/C++ are the only languages - with this feature. - - This is used for printing only, except by poorly designed C++ code. - For looking up a name, look for a symbol in the STRUCT_NAMESPACE. - One more legitimate use is that if TYPE_FLAG_STUB is set, this is - the name to use to look for definitions in other files. */ - - char *tag_name; - - /* Length, in units of TARGET_CHAR_BIT bits, - of storage for a value of this type */ - - unsigned length; - - /* Every type is now associated with a particular objfile, and the - type is allocated on the type_obstack for that objfile. One problem - however, is that there are times when gdb allocates new types while - it is not in the process of reading symbols from a particular objfile. - Fortunately, these happen when the type being created is a derived - type of an existing type, such as in lookup_pointer_type(). So - we can just allocate the new type using the same objfile as the - existing type, but to do this we need a backpointer to the objfile - from the existing type. Yes this is somewhat ugly, but without - major overhaul of the internal type system, it can't be avoided - for now. */ - - struct objfile *objfile; - - /* For a pointer type, describes the type of object pointed to. - For an array type, describes the type of the elements. - For a function or method type, describes the type of the return value. - For a range type, describes the type of the full range. - Unused otherwise. */ - - struct type *target_type; - - /* Type that is a pointer to this type. - NULL if no such pointer-to type is known yet. - The debugger may add the address of such a type - if it has to construct one later. */ - - struct type *pointer_type; - - /* C++: also need a reference type. */ - - struct type *reference_type; - - /* Type that is a function returning this type. - NULL if no such function type is known here. - The debugger may add the address of such a type - if it has to construct one later. */ - - struct type *function_type; - - /* Flags about this type. */ - - short flags; - - /* Number of fields described for this type */ - - short nfields; - - /* For structure and union types, a description of each field. - For set and pascal array types, there is one "field", - whose type is the domain type of the set or array. - For range types, there are two "fields", - the minimum and maximum values (both inclusive). - For enum types, each possible value is described by one "field". - For C++ classes, there is one field for each base class (if it is - a derived class) plus one field for each class data member. Member - functions are recorded elsewhere. - - Using a pointer to a separate array of fields - allows all types to have the same size, which is useful - because we can allocate the space for a type before - we know what to put in it. */ - - 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; - - /* 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. */ - - long bitsize; - - /* In a struct or enum type, type of this field. - In a function type, type of this argument. - In an array type, the domain-type of the array. */ - - struct type *type; - - /* Name of field, value or argument. - NULL for range bounds and array domains. */ - - char *name; - - } *fields; - - /* For types with virtual functions, 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. - - Unused otherwise. */ - - struct type *vptr_basetype; - - /* Field number of the virtual function table pointer in - VPTR_BASETYPE. If -1, we were unable to find the virtual - function table pointer in initial symbol reading, and - fill_in_vptr_fieldno should be called to find it if possible. - - Unused if this type does not have virtual functions. */ - - int vptr_fieldno; - - /* Slot to point to additional language-specific fields of this type. */ - - union type_specific - { - - /* ARG_TYPES is for TYPE_CODE_METHOD and TYPE_CODE_FUNC. */ - - struct type **arg_types; - - /* CPLUS_STUFF is for TYPE_CODE_STRUCT. It is initialized to point to - cplus_struct_default, a default static instance of a struct - cplus_struct_type. */ - - struct cplus_struct_type *cplus_stuff; - - } type_specific; -}; - -#define NULL_TYPE ((struct type *) 0) - -/* C++ language-specific information for TYPE_CODE_STRUCT and TYPE_CODE_UNION - nodes. */ - -struct cplus_struct_type -{ - /* Number of base classes this type derives from. The baseclasses are - stored in the first N_BASECLASSES fields (i.e. the `fields' field of - the struct type). I think only the `type' field of such a field has - any meaning. */ - - short n_baseclasses; - - /* Number of methods with unique names. All overloaded methods with - the same name count only once. */ - - short nfn_fields; - - /* Number of methods described for this type plus all the - methods that it derives from. */ - - int nfn_fields_total; - - /* 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. - I.E, given: - - class A{}; - class B{}; - class C : public B, public virtual A {}; - - B is a baseclass of C; A is a virtual baseclass for C. - This is a C++ 2.0 language feature. */ - - B_TYPE *virtual_field_bits; - - /* For classes with private fields, the number of fields is given by - nfields and private_field_bits is a bit vector containing one bit - per field. - If the field is private, the corresponding bit will be set. */ - - B_TYPE *private_field_bits; - - /* For classes with protected fields, the number of fields is given by - nfields and protected_field_bits is a bit vector containing one bit - per field. - If the field is private, the corresponding bit will be set. */ - - B_TYPE *protected_field_bits; - - /* for classes with fields to be ignored, either this is optimized out - or this field has length 0 */ - - B_TYPE *ignore_field_bits; - - /* For classes, structures, and unions, a description of each field, - which consists of an overloaded name, followed by the types of - arguments that the method expects, and then the name after it - has been renamed to make it distinct. - - fn_fieldlists points to an array of nfn_fields of these. */ - - struct fn_fieldlist - { - - /* The overloaded name. */ - - char *name; - - /* The number of methods with this name. */ - - int length; - - /* The list of methods. */ - - struct fn_field - { - - /* If is_stub is clear, this is the mangled name which we can - look up to find the address of the method (FIXME: it would - be cleaner to have a pointer to the struct symbol here - instead). */ - - /* If is_stub is set, this is the portion of the mangled - name which specifies the arguments. For example, "ii", - if there are two int arguments, or "" if there are no - arguments. See gdb_mangle_name for the conversion from this - format to the one used if is_stub is clear. */ - - char *physname; - - /* The return value of the method */ - - struct type *type; - - /* The argument list. Only valid if is_stub is clear. Contains - the type of each argument, including `this', and ending with - a NULL pointer after the last argument. Should not contain - a `this' pointer for static member functions. */ - - struct type **args; - - /* For virtual functions. - First baseclass that defines this virtual function. */ - - struct type *fcontext; - - /* Attributes. */ - - unsigned int is_const : 1; - unsigned int is_volatile : 1; - unsigned int is_private : 1; - unsigned int is_protected : 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; - - /* Unused. */ - unsigned int dummy : 3; - - /* Index into that baseclass's virtual function table, - minus 2; else if static: VOFFSET_STATIC; else: 0. */ - - unsigned int voffset : 24; - -# define VOFFSET_STATIC 1 - - } *fn_fields; - - } *fn_fieldlists; - -}; - -/* The default value of TYPE_CPLUS_SPECIFIC(T) points to the - this shared static structure. */ - -extern const struct cplus_struct_type cplus_struct_default; - -extern void -allocate_cplus_struct_type PARAMS ((struct type *)); - -#define INIT_CPLUS_SPECIFIC(type) \ - (TYPE_CPLUS_SPECIFIC(type)=(struct cplus_struct_type*)&cplus_struct_default) -#define ALLOCATE_CPLUS_STRUCT_TYPE(type) allocate_cplus_struct_type (type) -#define HAVE_CPLUS_STRUCT(type) \ - (TYPE_CPLUS_SPECIFIC(type) != &cplus_struct_default) - -#define TYPE_NAME(thistype) (thistype)->name -#define TYPE_TAG_NAME(type) ((type)->tag_name) -#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_FUNCTION_TYPE(thistype) (thistype)->function_type -#define TYPE_LENGTH(thistype) (thistype)->length -#define TYPE_OBJFILE(thistype) (thistype)->objfile -#define TYPE_FLAGS(thistype) (thistype)->flags -#define TYPE_UNSIGNED(thistype) ((thistype)->flags & TYPE_FLAG_UNSIGNED) -#define TYPE_CODE(thistype) (thistype)->code -#define TYPE_NFIELDS(thistype) (thistype)->nfields -#define TYPE_FIELDS(thistype) (thistype)->fields - -#define TYPE_LOW_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 0) -#define TYPE_HIGH_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 1) -/* If TYPE_DUMMY_RANGE is true for a range type, it was allocated - by force_to_range_type. */ -#define TYPE_DUMMY_RANGE(type) ((type)->vptr_fieldno) - -/* C++ */ - -#define TYPE_VPTR_BASETYPE(thistype) (thistype)->vptr_basetype -#define TYPE_DOMAIN_TYPE(thistype) (thistype)->vptr_basetype -#define TYPE_VPTR_FIELDNO(thistype) (thistype)->vptr_fieldno -#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_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_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_PRIVATE_BITS(thistype) \ - TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits -#define TYPE_FIELD_PROTECTED_BITS(thistype) \ - TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits -#define TYPE_FIELD_IGNORE_BITS(thistype) \ - TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits -#define TYPE_FIELD_VIRTUAL_BITS(thistype) \ - TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits -#define SET_TYPE_FIELD_PRIVATE(thistype, n) \ - B_SET (TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits, (n)) -#define SET_TYPE_FIELD_PROTECTED(thistype, n) \ - B_SET (TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n)) -#define SET_TYPE_FIELD_IGNORE(thistype, n) \ - B_SET (TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits, (n)) -#define SET_TYPE_FIELD_VIRTUAL(thistype, n) \ - B_SET (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n)) -#define TYPE_FIELD_PRIVATE(thistype, n) \ - (TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits == NULL ? 0 \ - : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits, (n))) -#define TYPE_FIELD_PROTECTED(thistype, n) \ - (TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits == NULL ? 0 \ - : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n))) -#define TYPE_FIELD_IGNORE(thistype, n) \ - (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)) - -#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_FN_FIELDLISTS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists -#define TYPE_FN_FIELDLIST(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n] -#define TYPE_FN_FIELDLIST1(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].fn_fields -#define TYPE_FN_FIELDLIST_NAME(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].name -#define TYPE_FN_FIELDLIST_LENGTH(thistype, n) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists[n].length - -#define TYPE_FN_FIELD(thisfn, n) (thisfn)[n] -#define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname -#define TYPE_FN_FIELD_TYPE(thisfn, n) (thisfn)[n].type -#define TYPE_FN_FIELD_ARGS(thisfn, n) TYPE_ARG_TYPES ((thisfn)[n].type) -#define TYPE_FN_FIELD_CONST(thisfn, n) ((thisfn)[n].is_const) -#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_STUB(thisfn, n) ((thisfn)[n].is_stub) -#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) - -extern struct type *builtin_type_void; -extern struct type *builtin_type_char; -extern struct type *builtin_type_short; -extern struct type *builtin_type_int; -extern struct type *builtin_type_long; -extern struct type *builtin_type_signed_char; -extern struct type *builtin_type_unsigned_char; -extern struct type *builtin_type_unsigned_short; -extern struct type *builtin_type_unsigned_int; -extern struct type *builtin_type_unsigned_long; -extern struct type *builtin_type_float; -extern struct type *builtin_type_double; -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; - -/* This type represents a type that was unrecognized in symbol - read-in. */ - -extern struct type *builtin_type_error; - -extern struct type *builtin_type_long_long; -extern struct type *builtin_type_unsigned_long_long; - -/* Modula-2 types */ - -extern struct type *builtin_type_m2_char; -extern struct type *builtin_type_m2_int; -extern struct type *builtin_type_m2_card; -extern struct type *builtin_type_m2_real; -extern struct type *builtin_type_m2_bool; - -/* Chill types */ - -extern struct type *builtin_type_chill_bool; -extern struct type *builtin_type_chill_char; -extern struct type *builtin_type_chill_long; -extern struct type *builtin_type_chill_ulong; -extern struct type *builtin_type_chill_real; - -/* Maximum and minimum values of built-in types */ - -#define MAX_OF_TYPE(t) \ - TYPE_UNSIGNED(t) ? UMAX_OF_SIZE(TYPE_LENGTH(t)) \ - : MAX_OF_SIZE(TYPE_LENGTH(t)) - -#define MIN_OF_TYPE(t) \ - TYPE_UNSIGNED(t) ? UMIN_OF_SIZE(TYPE_LENGTH(t)) \ - : MIN_OF_SIZE(TYPE_LENGTH(t)) - -/* Allocate space for storing data associated with a particular type. - We ensure that the space is allocated using the same mechanism that - was used to allocate the space for the type structure itself. I.E. - if the type is on an objfile's type_obstack, then the space for data - associated with that type will also be allocated on the type_obstack. - If the type is not associated with any particular objfile (such as - builtin types), then the data space will be allocated with xmalloc, - the same as for the type structure. */ - -#define TYPE_ALLOC(t,size) \ - (TYPE_OBJFILE (t) != NULL \ - ? obstack_alloc (&TYPE_OBJFILE (t) -> type_obstack, size) \ - : xmalloc (size)) - -extern struct type * -alloc_type PARAMS ((struct objfile *)); - -extern struct type * -init_type PARAMS ((enum type_code, int, int, char *, struct objfile *)); - -extern struct type * -lookup_reference_type PARAMS ((struct type *)); - -extern struct type * -make_reference_type PARAMS ((struct type *, struct type **)); - -extern struct type * -lookup_member_type PARAMS ((struct type *, struct type *)); - -extern void -smash_to_method_type PARAMS ((struct type *, struct type *, struct type *, - struct type **)); - -extern void -smash_to_member_type PARAMS ((struct type *, struct type *, struct type *)); - -extern struct type * -allocate_stub_method PARAMS ((struct type *)); - -extern char * -type_name_no_tag PARAMS ((const struct type *)); - -extern struct type * -lookup_struct_elt_type PARAMS ((struct type *, char *, int)); - -extern struct type * -make_pointer_type PARAMS ((struct type *, struct type **)); - -extern struct type * -lookup_pointer_type PARAMS ((struct type *)); - -extern struct type * -make_function_type PARAMS ((struct type *, struct type **)); - -extern struct type * -lookup_function_type PARAMS ((struct type *)); - -extern struct type * -create_range_type PARAMS ((struct type *, struct type *, int, int)); - -extern struct type * -create_array_type PARAMS ((struct type *, struct type *, struct type *)); - -extern struct type * -create_string_type PARAMS ((struct type *, struct type *)); - -extern struct type * -create_set_type PARAMS ((struct type *, struct type *)); - -extern struct type * -lookup_unsigned_typename PARAMS ((char *)); - -extern struct type * -lookup_signed_typename PARAMS ((char *)); - -extern void -check_stub_type PARAMS ((struct type *)); - -extern void -check_stub_method PARAMS ((struct type *, int, int)); - -extern struct type * -lookup_primitive_typename PARAMS ((char *)); - -extern char * -gdb_mangle_name PARAMS ((struct type *, int, int)); - -extern struct type * -builtin_type PARAMS ((char **)); - -extern struct type * -lookup_typename PARAMS ((char *, struct block *, int)); - -extern struct type * -lookup_template_type PARAMS ((char *, struct type *, struct block *)); - -extern struct type * -lookup_fundamental_type PARAMS ((struct objfile *, int)); - -extern void -fill_in_vptr_fieldno PARAMS ((struct type *)); - -#if MAINTENANCE_CMDS -extern void recursive_dump_type PARAMS ((struct type *, int)); -#endif - -/* printcmd.c */ - -extern void -print_scalar_formatted PARAMS ((char *, struct type *, int, int, GDB_FILE *)); - -extern int can_dereference PARAMS ((struct type *)); - -#if MAINTENANCE_CMDS -extern void maintenance_print_type PARAMS ((char *, int)); -#endif - -#endif /* GDBTYPES_H */ diff --git a/gnu/usr.bin/gdb/gdb/getopt.h b/gnu/usr.bin/gdb/gdb/getopt.h deleted file mode 100644 index 1b546b2..0000000 --- a/gnu/usr.bin/gdb/gdb/getopt.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library 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 Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this program; if not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -#if __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -#if __STDC__ -#if defined(__GNU_LIBRARY__) -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int argc, char *const *argv, const char *shortopts); -#else /* not __GNU_LIBRARY__ */ -extern int getopt (); -#endif /* not __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -#endif /* not __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/gnu/usr.bin/gdb/gdb/i386-dis.c b/gnu/usr.bin/gdb/gdb/i386-dis.c deleted file mode 100644 index ff94b3d8..0000000 --- a/gnu/usr.bin/gdb/gdb/i386-dis.c +++ /dev/null @@ -1,1959 +0,0 @@ -/* Print i386 instructions for GDB, the GNU debugger. - Copyright (C) 1988, 1989, 1991, 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. */ - -/* - * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) - * July 1988 - * modified by John Hassey (hassey@dg-rtp.dg.com) - */ - -/* - * The main tables describing the instructions is essentially a copy - * of the "Opcode Map" chapter (Appendix A) of the Intel 80386 - * Programmers Manual. Usually, there is a capital letter, followed - * by a small letter. The capital letter tell the addressing mode, - * and the small letter tells about the operand size. Refer to - * the Intel manual for details. - */ - -#include "dis-asm.h" -#include "sysdep.h" - -#define MAXLEN 20 - -#include - -struct dis_private -{ - /* Points to first byte not fetched. */ - bfd_byte *max_fetched; - bfd_byte the_buffer[MAXLEN]; - bfd_vma insn_start; - jmp_buf bailout; -}; - -/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) - to ADDR (exclusive) are valid. Returns 1 for success, longjmps - on error. */ -#define FETCH_DATA(info, addr) \ - ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \ - ? 1 : fetch_data ((info), (addr))) - -static int -fetch_data (info, addr) - struct disassemble_info *info; - bfd_byte *addr; -{ - int status; - struct dis_private *priv = (struct dis_private *)info->private_data; - bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); - - status = (*info->read_memory_func) (start, - priv->max_fetched, - addr - priv->max_fetched, - info); - if (status != 0) - { - (*info->memory_error_func) (status, start, info); - longjmp (priv->bailout, 1); - } - else - priv->max_fetched = addr; - return 1; -} - -#define Eb OP_E, b_mode -#define indirEb OP_indirE, b_mode -#define Gb OP_G, b_mode -#define Ev OP_E, v_mode -#define indirEv OP_indirE, v_mode -#define Ew OP_E, w_mode -#define Ma OP_E, v_mode -#define M OP_E, 0 -#define Mp OP_E, 0 /* ? */ -#define Gv OP_G, v_mode -#define Gw OP_G, w_mode -#define Rw OP_rm, w_mode -#define Rd OP_rm, d_mode -#define Ib OP_I, b_mode -#define sIb OP_sI, b_mode /* sign extened byte */ -#define Iv OP_I, v_mode -#define Iw OP_I, w_mode -#define Jb OP_J, b_mode -#define Jv OP_J, v_mode -#define ONE OP_ONE, 0 -#define Cd OP_C, d_mode -#define Dd OP_D, d_mode -#define Td OP_T, d_mode - -#define eAX OP_REG, eAX_reg -#define eBX OP_REG, eBX_reg -#define eCX OP_REG, eCX_reg -#define eDX OP_REG, eDX_reg -#define eSP OP_REG, eSP_reg -#define eBP OP_REG, eBP_reg -#define eSI OP_REG, eSI_reg -#define eDI OP_REG, eDI_reg -#define AL OP_REG, al_reg -#define CL OP_REG, cl_reg -#define DL OP_REG, dl_reg -#define BL OP_REG, bl_reg -#define AH OP_REG, ah_reg -#define CH OP_REG, ch_reg -#define DH OP_REG, dh_reg -#define BH OP_REG, bh_reg -#define AX OP_REG, ax_reg -#define DX OP_REG, dx_reg -#define indirDX OP_REG, indir_dx_reg - -#define Sw OP_SEG, w_mode -#define Ap OP_DIR, lptr -#define Av OP_DIR, v_mode -#define Ob OP_OFF, b_mode -#define Ov OP_OFF, v_mode -#define Xb OP_DSSI, b_mode -#define Xv OP_DSSI, v_mode -#define Yb OP_ESDI, b_mode -#define Yv OP_ESDI, v_mode - -#define es OP_REG, es_reg -#define ss OP_REG, ss_reg -#define cs OP_REG, cs_reg -#define ds OP_REG, ds_reg -#define fs OP_REG, fs_reg -#define gs OP_REG, gs_reg - -int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG(); -int OP_J(), OP_SEG(); -int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C(); -int OP_D(), OP_T(), OP_rm(); - -static void dofloat (), putop (), append_prefix (), set_op (); -static int get16 (), get32 (); - -#define b_mode 1 -#define v_mode 2 -#define w_mode 3 -#define d_mode 4 - -#define es_reg 100 -#define cs_reg 101 -#define ss_reg 102 -#define ds_reg 103 -#define fs_reg 104 -#define gs_reg 105 -#define eAX_reg 107 -#define eCX_reg 108 -#define eDX_reg 109 -#define eBX_reg 110 -#define eSP_reg 111 -#define eBP_reg 112 -#define eSI_reg 113 -#define eDI_reg 114 - -#define lptr 115 - -#define al_reg 116 -#define cl_reg 117 -#define dl_reg 118 -#define bl_reg 119 -#define ah_reg 120 -#define ch_reg 121 -#define dh_reg 122 -#define bh_reg 123 - -#define ax_reg 124 -#define cx_reg 125 -#define dx_reg 126 -#define bx_reg 127 -#define sp_reg 128 -#define bp_reg 129 -#define si_reg 130 -#define di_reg 131 - -#define indir_dx_reg 150 - -#define GRP1b NULL, NULL, 0 -#define GRP1S NULL, NULL, 1 -#define GRP1Ss NULL, NULL, 2 -#define GRP2b NULL, NULL, 3 -#define GRP2S NULL, NULL, 4 -#define GRP2b_one NULL, NULL, 5 -#define GRP2S_one NULL, NULL, 6 -#define GRP2b_cl NULL, NULL, 7 -#define GRP2S_cl NULL, NULL, 8 -#define GRP3b NULL, NULL, 9 -#define GRP3S NULL, NULL, 10 -#define GRP4 NULL, NULL, 11 -#define GRP5 NULL, NULL, 12 -#define GRP6 NULL, NULL, 13 -#define GRP7 NULL, NULL, 14 -#define GRP8 NULL, NULL, 15 - -#define FLOATCODE 50 -#define FLOAT NULL, NULL, FLOATCODE - -struct dis386 { - char *name; - int (*op1)(); - int bytemode1; - int (*op2)(); - int bytemode2; - int (*op3)(); - int bytemode3; -}; - -struct dis386 dis386[] = { - /* 00 */ - { "addb", Eb, Gb }, - { "addS", Ev, Gv }, - { "addb", Gb, Eb }, - { "addS", Gv, Ev }, - { "addb", AL, Ib }, - { "addS", eAX, Iv }, - { "pushl", es }, - { "popl", es }, - /* 08 */ - { "orb", Eb, Gb }, - { "orS", Ev, Gv }, - { "orb", Gb, Eb }, - { "orS", Gv, Ev }, - { "orb", AL, Ib }, - { "orS", eAX, Iv }, - { "pushl", cs }, - { "(bad)" }, /* 0x0f extended opcode escape */ - /* 10 */ - { "adcb", Eb, Gb }, - { "adcS", Ev, Gv }, - { "adcb", Gb, Eb }, - { "adcS", Gv, Ev }, - { "adcb", AL, Ib }, - { "adcS", eAX, Iv }, - { "pushl", ss }, - { "popl", ss }, - /* 18 */ - { "sbbb", Eb, Gb }, - { "sbbS", Ev, Gv }, - { "sbbb", Gb, Eb }, - { "sbbS", Gv, Ev }, - { "sbbb", AL, Ib }, - { "sbbS", eAX, Iv }, - { "pushl", ds }, - { "popl", ds }, - /* 20 */ - { "andb", Eb, Gb }, - { "andS", Ev, Gv }, - { "andb", Gb, Eb }, - { "andS", Gv, Ev }, - { "andb", AL, Ib }, - { "andS", eAX, Iv }, - { "(bad)" }, /* SEG ES prefix */ - { "daa" }, - /* 28 */ - { "subb", Eb, Gb }, - { "subS", Ev, Gv }, - { "subb", Gb, Eb }, - { "subS", Gv, Ev }, - { "subb", AL, Ib }, - { "subS", eAX, Iv }, - { "(bad)" }, /* SEG CS prefix */ - { "das" }, - /* 30 */ - { "xorb", Eb, Gb }, - { "xorS", Ev, Gv }, - { "xorb", Gb, Eb }, - { "xorS", Gv, Ev }, - { "xorb", AL, Ib }, - { "xorS", eAX, Iv }, - { "(bad)" }, /* SEG SS prefix */ - { "aaa" }, - /* 38 */ - { "cmpb", Eb, Gb }, - { "cmpS", Ev, Gv }, - { "cmpb", Gb, Eb }, - { "cmpS", Gv, Ev }, - { "cmpb", AL, Ib }, - { "cmpS", eAX, Iv }, - { "(bad)" }, /* SEG DS prefix */ - { "aas" }, - /* 40 */ - { "incS", eAX }, - { "incS", eCX }, - { "incS", eDX }, - { "incS", eBX }, - { "incS", eSP }, - { "incS", eBP }, - { "incS", eSI }, - { "incS", eDI }, - /* 48 */ - { "decS", eAX }, - { "decS", eCX }, - { "decS", eDX }, - { "decS", eBX }, - { "decS", eSP }, - { "decS", eBP }, - { "decS", eSI }, - { "decS", eDI }, - /* 50 */ - { "pushS", eAX }, - { "pushS", eCX }, - { "pushS", eDX }, - { "pushS", eBX }, - { "pushS", eSP }, - { "pushS", eBP }, - { "pushS", eSI }, - { "pushS", eDI }, - /* 58 */ - { "popS", eAX }, - { "popS", eCX }, - { "popS", eDX }, - { "popS", eBX }, - { "popS", eSP }, - { "popS", eBP }, - { "popS", eSI }, - { "popS", eDI }, - /* 60 */ - { "pusha" }, - { "popa" }, - { "boundS", Gv, Ma }, - { "arpl", Ew, Gw }, - { "(bad)" }, /* seg fs */ - { "(bad)" }, /* seg gs */ - { "(bad)" }, /* op size prefix */ - { "(bad)" }, /* adr size prefix */ - /* 68 */ - { "pushS", Iv }, /* 386 book wrong */ - { "imulS", Gv, Ev, Iv }, - { "pushl", sIb }, /* push of byte really pushes 4 bytes */ - { "imulS", Gv, Ev, Ib }, - { "insb", Yb, indirDX }, - { "insS", Yv, indirDX }, - { "outsb", indirDX, Xb }, - { "outsS", indirDX, Xv }, - /* 70 */ - { "jo", Jb }, - { "jno", Jb }, - { "jb", Jb }, - { "jae", Jb }, - { "je", Jb }, - { "jne", Jb }, - { "jbe", Jb }, - { "ja", Jb }, - /* 78 */ - { "js", Jb }, - { "jns", Jb }, - { "jp", Jb }, - { "jnp", Jb }, - { "jl", Jb }, - { "jnl", Jb }, - { "jle", Jb }, - { "jg", Jb }, - /* 80 */ - { GRP1b }, - { GRP1S }, - { "(bad)" }, - { GRP1Ss }, - { "testb", Eb, Gb }, - { "testS", Ev, Gv }, - { "xchgb", Eb, Gb }, - { "xchgS", Ev, Gv }, - /* 88 */ - { "movb", Eb, Gb }, - { "movS", Ev, Gv }, - { "movb", Gb, Eb }, - { "movS", Gv, Ev }, - { "movw", Ew, Sw }, - { "leaS", Gv, M }, - { "movw", Sw, Ew }, - { "popS", Ev }, - /* 90 */ - { "nop" }, - { "xchgS", eCX, eAX }, - { "xchgS", eDX, eAX }, - { "xchgS", eBX, eAX }, - { "xchgS", eSP, eAX }, - { "xchgS", eBP, eAX }, - { "xchgS", eSI, eAX }, - { "xchgS", eDI, eAX }, - /* 98 */ - { "cwtl" }, - { "cltd" }, - { "lcall", Ap }, - { "(bad)" }, /* fwait */ - { "pushf" }, - { "popf" }, - { "sahf" }, - { "lahf" }, - /* a0 */ - { "movb", AL, Ob }, - { "movS", eAX, Ov }, - { "movb", Ob, AL }, - { "movS", Ov, eAX }, - { "movsb", Yb, Xb }, - { "movsS", Yv, Xv }, - { "cmpsb", Yb, Xb }, - { "cmpsS", Yv, Xv }, - /* a8 */ - { "testb", AL, Ib }, - { "testS", eAX, Iv }, - { "stosb", Yb, AL }, - { "stosS", Yv, eAX }, - { "lodsb", AL, Xb }, - { "lodsS", eAX, Xv }, - { "scasb", AL, Yb }, - { "scasS", eAX, Yv }, - /* b0 */ - { "movb", AL, Ib }, - { "movb", CL, Ib }, - { "movb", DL, Ib }, - { "movb", BL, Ib }, - { "movb", AH, Ib }, - { "movb", CH, Ib }, - { "movb", DH, Ib }, - { "movb", BH, Ib }, - /* b8 */ - { "movS", eAX, Iv }, - { "movS", eCX, Iv }, - { "movS", eDX, Iv }, - { "movS", eBX, Iv }, - { "movS", eSP, Iv }, - { "movS", eBP, Iv }, - { "movS", eSI, Iv }, - { "movS", eDI, Iv }, - /* c0 */ - { GRP2b }, - { GRP2S }, - { "ret", Iw }, - { "ret" }, - { "lesS", Gv, Mp }, - { "ldsS", Gv, Mp }, - { "movb", Eb, Ib }, - { "movS", Ev, Iv }, - /* c8 */ - { "enter", Iw, Ib }, - { "leave" }, - { "lret", Iw }, - { "lret" }, - { "int3" }, - { "int", Ib }, - { "into" }, - { "iret" }, - /* d0 */ - { GRP2b_one }, - { GRP2S_one }, - { GRP2b_cl }, - { GRP2S_cl }, - { "aam", Ib }, - { "aad", Ib }, - { "(bad)" }, - { "xlat" }, - /* d8 */ - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - /* e0 */ - { "loopne", Jb }, - { "loope", Jb }, - { "loop", Jb }, - { "jCcxz", Jb }, - { "inb", AL, Ib }, - { "inS", eAX, Ib }, - { "outb", Ib, AL }, - { "outS", Ib, eAX }, - /* e8 */ - { "call", Av }, - { "jmp", Jv }, - { "ljmp", Ap }, - { "jmp", Jb }, - { "inb", AL, indirDX }, - { "inS", eAX, indirDX }, - { "outb", indirDX, AL }, - { "outS", indirDX, eAX }, - /* f0 */ - { "(bad)" }, /* lock prefix */ - { "(bad)" }, - { "(bad)" }, /* repne */ - { "(bad)" }, /* repz */ - { "hlt" }, - { "cmc" }, - { GRP3b }, - { GRP3S }, - /* f8 */ - { "clc" }, - { "stc" }, - { "cli" }, - { "sti" }, - { "cld" }, - { "std" }, - { GRP4 }, - { GRP5 }, -}; - -struct dis386 dis386_twobyte[] = { - /* 00 */ - { GRP6 }, - { GRP7 }, - { "larS", Gv, Ew }, - { "lslS", Gv, Ew }, - { "(bad)" }, - { "(bad)" }, - { "clts" }, - { "(bad)" }, - /* 08 */ - { "invd" }, - { "wbinvd" }, - { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 10 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 18 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 20 */ - /* these are all backward in appendix A of the intel book */ - { "movl", Rd, Cd }, - { "movl", Rd, Dd }, - { "movl", Cd, Rd }, - { "movl", Dd, Rd }, - { "movl", Rd, Td }, - { "(bad)" }, - { "movl", Td, Rd }, - { "(bad)" }, - /* 28 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 30 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 38 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 40 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 48 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 50 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 58 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 60 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 68 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 70 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 78 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* 80 */ - { "jo", Jv }, - { "jno", Jv }, - { "jb", Jv }, - { "jae", Jv }, - { "je", Jv }, - { "jne", Jv }, - { "jbe", Jv }, - { "ja", Jv }, - /* 88 */ - { "js", Jv }, - { "jns", Jv }, - { "jp", Jv }, - { "jnp", Jv }, - { "jl", Jv }, - { "jge", Jv }, - { "jle", Jv }, - { "jg", Jv }, - /* 90 */ - { "seto", Eb }, - { "setno", Eb }, - { "setb", Eb }, - { "setae", Eb }, - { "sete", Eb }, - { "setne", Eb }, - { "setbe", Eb }, - { "seta", Eb }, - /* 98 */ - { "sets", Eb }, - { "setns", Eb }, - { "setp", Eb }, - { "setnp", Eb }, - { "setl", Eb }, - { "setge", Eb }, - { "setle", Eb }, - { "setg", Eb }, - /* a0 */ - { "pushl", fs }, - { "popl", fs }, - { "(bad)" }, - { "btS", Ev, Gv }, - { "shldS", Ev, Gv, Ib }, - { "shldS", Ev, Gv, CL }, - { "(bad)" }, - { "(bad)" }, - /* a8 */ - { "pushl", gs }, - { "popl", gs }, - { "(bad)" }, - { "btsS", Ev, Gv }, - { "shrdS", Ev, Gv, Ib }, - { "shrdS", Ev, Gv, CL }, - { "(bad)" }, - { "imulS", Gv, Ev }, - /* b0 */ - { "cmpxchgb", Eb, Gb }, - { "cmpxchgS", Ev, Gv }, - { "lssS", Gv, Mp }, /* 386 lists only Mp */ - { "btrS", Ev, Gv }, - { "lfsS", Gv, Mp }, /* 386 lists only Mp */ - { "lgsS", Gv, Mp }, /* 386 lists only Mp */ - { "movzbS", Gv, Eb }, - { "movzwS", Gv, Ew }, - /* b8 */ - { "(bad)" }, - { "(bad)" }, - { GRP8 }, - { "btcS", Ev, Gv }, - { "bsfS", Gv, Ev }, - { "bsrS", Gv, Ev }, - { "movsbS", Gv, Eb }, - { "movswS", Gv, Ew }, - /* c0 */ - { "xaddb", Eb, Gb }, - { "xaddS", Ev, Gv }, - { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* c8 */ - { "bswap", eAX }, - { "bswap", eCX }, - { "bswap", eDX }, - { "bswap", eBX }, - { "bswap", eSP }, - { "bswap", eBP }, - { "bswap", eSI }, - { "bswap", eDI }, - /* d0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* d8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* e0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* e8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* f0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - /* f8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, -}; - -static char obuf[100]; -static char *obufp; -static char scratchbuf[100]; -static unsigned char *start_codep; -static unsigned char *codep; -static disassemble_info *the_info; -static int mod; -static int rm; -static int reg; -static void oappend (); - -static char *names32[]={ - "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi", -}; -static char *names16[] = { - "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di", -}; -static char *names8[] = { - "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh", -}; -static char *names_seg[] = { - "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", -}; - -struct dis386 grps[][8] = { - /* GRP1b */ - { - { "addb", Eb, Ib }, - { "orb", Eb, Ib }, - { "adcb", Eb, Ib }, - { "sbbb", Eb, Ib }, - { "andb", Eb, Ib }, - { "subb", Eb, Ib }, - { "xorb", Eb, Ib }, - { "cmpb", Eb, Ib } - }, - /* GRP1S */ - { - { "addS", Ev, Iv }, - { "orS", Ev, Iv }, - { "adcS", Ev, Iv }, - { "sbbS", Ev, Iv }, - { "andS", Ev, Iv }, - { "subS", Ev, Iv }, - { "xorS", Ev, Iv }, - { "cmpS", Ev, Iv } - }, - /* GRP1Ss */ - { - { "addS", Ev, sIb }, - { "orS", Ev, sIb }, - { "adcS", Ev, sIb }, - { "sbbS", Ev, sIb }, - { "andS", Ev, sIb }, - { "subS", Ev, sIb }, - { "xorS", Ev, sIb }, - { "cmpS", Ev, sIb } - }, - /* GRP2b */ - { - { "rolb", Eb, Ib }, - { "rorb", Eb, Ib }, - { "rclb", Eb, Ib }, - { "rcrb", Eb, Ib }, - { "shlb", Eb, Ib }, - { "shrb", Eb, Ib }, - { "(bad)" }, - { "sarb", Eb, Ib }, - }, - /* GRP2S */ - { - { "rolS", Ev, Ib }, - { "rorS", Ev, Ib }, - { "rclS", Ev, Ib }, - { "rcrS", Ev, Ib }, - { "shlS", Ev, Ib }, - { "shrS", Ev, Ib }, - { "(bad)" }, - { "sarS", Ev, Ib }, - }, - /* GRP2b_one */ - { - { "rolb", Eb }, - { "rorb", Eb }, - { "rclb", Eb }, - { "rcrb", Eb }, - { "shlb", Eb }, - { "shrb", Eb }, - { "(bad)" }, - { "sarb", Eb }, - }, - /* GRP2S_one */ - { - { "rolS", Ev }, - { "rorS", Ev }, - { "rclS", Ev }, - { "rcrS", Ev }, - { "shlS", Ev }, - { "shrS", Ev }, - { "(bad)" }, - { "sarS", Ev }, - }, - /* GRP2b_cl */ - { - { "rolb", Eb, CL }, - { "rorb", Eb, CL }, - { "rclb", Eb, CL }, - { "rcrb", Eb, CL }, - { "shlb", Eb, CL }, - { "shrb", Eb, CL }, - { "(bad)" }, - { "sarb", Eb, CL }, - }, - /* GRP2S_cl */ - { - { "rolS", Ev, CL }, - { "rorS", Ev, CL }, - { "rclS", Ev, CL }, - { "rcrS", Ev, CL }, - { "shlS", Ev, CL }, - { "shrS", Ev, CL }, - { "(bad)" }, - { "sarS", Ev, CL } - }, - /* GRP3b */ - { - { "testb", Eb, Ib }, - { "(bad)", Eb }, - { "notb", Eb }, - { "negb", Eb }, - { "mulb", AL, Eb }, - { "imulb", AL, Eb }, - { "divb", AL, Eb }, - { "idivb", AL, Eb } - }, - /* GRP3S */ - { - { "testS", Ev, Iv }, - { "(bad)" }, - { "notS", Ev }, - { "negS", Ev }, - { "mulS", eAX, Ev }, - { "imulS", eAX, Ev }, - { "divS", eAX, Ev }, - { "idivS", eAX, Ev }, - }, - /* GRP4 */ - { - { "incb", Eb }, - { "decb", Eb }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - }, - /* GRP5 */ - { - { "incS", Ev }, - { "decS", Ev }, - { "call", indirEv }, - { "lcall", indirEv }, - { "jmp", indirEv }, - { "ljmp", indirEv }, - { "pushS", Ev }, - { "(bad)" }, - }, - /* GRP6 */ - { - { "sldt", Ew }, - { "str", Ew }, - { "lldt", Ew }, - { "ltr", Ew }, - { "verr", Ew }, - { "verw", Ew }, - { "(bad)" }, - { "(bad)" } - }, - /* GRP7 */ - { - { "sgdt", Ew }, - { "sidt", Ew }, - { "lgdt", Ew }, - { "lidt", Ew }, - { "smsw", Ew }, - { "(bad)" }, - { "lmsw", Ew }, - { "invlpg", Ew }, - }, - /* GRP8 */ - { - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "btS", Ev, Ib }, - { "btsS", Ev, Ib }, - { "btrS", Ev, Ib }, - { "btcS", Ev, Ib }, - } -}; - -#define PREFIX_REPZ 1 -#define PREFIX_REPNZ 2 -#define PREFIX_LOCK 4 -#define PREFIX_CS 8 -#define PREFIX_SS 0x10 -#define PREFIX_DS 0x20 -#define PREFIX_ES 0x40 -#define PREFIX_FS 0x80 -#define PREFIX_GS 0x100 -#define PREFIX_DATA 0x200 -#define PREFIX_ADR 0x400 -#define PREFIX_FWAIT 0x800 - -static int prefixes; - -static void -ckprefix () -{ - prefixes = 0; - while (1) - { - FETCH_DATA (the_info, codep + 1); - switch (*codep) - { - case 0xf3: - prefixes |= PREFIX_REPZ; - break; - case 0xf2: - prefixes |= PREFIX_REPNZ; - break; - case 0xf0: - prefixes |= PREFIX_LOCK; - break; - case 0x2e: - prefixes |= PREFIX_CS; - break; - case 0x36: - prefixes |= PREFIX_SS; - break; - case 0x3e: - prefixes |= PREFIX_DS; - break; - case 0x26: - prefixes |= PREFIX_ES; - break; - case 0x64: - prefixes |= PREFIX_FS; - break; - case 0x65: - prefixes |= PREFIX_GS; - break; - case 0x66: - prefixes |= PREFIX_DATA; - break; - case 0x67: - prefixes |= PREFIX_ADR; - break; - case 0x9b: - prefixes |= PREFIX_FWAIT; - break; - default: - return; - } - codep++; - } -} - -static int dflag; -static int aflag; - -static char op1out[100], op2out[100], op3out[100]; -static int op_address[3], op_ad, op_index[3]; -static int start_pc; - - -/* - * On the 386's of 1988, the maximum length of an instruction is 15 bytes. - * (see topic "Redundant prefixes" in the "Differences from 8086" - * section of the "Virtual 8086 Mode" chapter.) - * 'pc' should be the address of this instruction, it will - * be used to print the target address if this is a relative jump or call - * The function returns the length of this instruction in bytes. - */ - -int -print_insn_i386 (pc, info) - bfd_vma pc; - disassemble_info *info; -{ - struct dis386 *dp; - int i; - int enter_instruction; - char *first, *second, *third; - int needcomma; - - struct dis_private priv; - bfd_byte *inbuf = priv.the_buffer; - - info->private_data = (PTR) &priv; - priv.max_fetched = priv.the_buffer; - priv.insn_start = pc; - if (setjmp (priv.bailout) != 0) - /* Error return. */ - return -1; - - obuf[0] = 0; - op1out[0] = 0; - op2out[0] = 0; - op3out[0] = 0; - - op_index[0] = op_index[1] = op_index[2] = -1; - - the_info = info; - start_pc = pc; - start_codep = inbuf; - codep = inbuf; - - ckprefix (); - - FETCH_DATA (info, codep + 1); - if (*codep == 0xc8) - enter_instruction = 1; - else - enter_instruction = 0; - - obufp = obuf; - - if (prefixes & PREFIX_REPZ) - oappend ("repz "); - if (prefixes & PREFIX_REPNZ) - oappend ("repnz "); - if (prefixes & PREFIX_LOCK) - oappend ("lock "); - - if ((prefixes & PREFIX_FWAIT) - && ((*codep < 0xd8) || (*codep > 0xdf))) - { - /* fwait not followed by floating point instruction */ - (*info->fprintf_func) (info->stream, "fwait"); - return (1); - } - - /* these would be initialized to 0 if disassembling for 8086 or 286 */ - dflag = 1; - aflag = 1; - - if (prefixes & PREFIX_DATA) - dflag ^= 1; - - if (prefixes & PREFIX_ADR) - { - aflag ^= 1; - oappend ("addr16 "); - } - - if (*codep == 0x0f) - { - FETCH_DATA (info, codep + 2); - dp = &dis386_twobyte[*++codep]; - } - else - dp = &dis386[*codep]; - codep++; - - /* Fetch the mod/reg/rm byte. FIXME: We should be only fetching - this if we need it. As it is, this code loses if there is a - one-byte instruction (without a mod/reg/rm byte) at the end of - the address space. */ - - FETCH_DATA (info, codep + 1); - mod = (*codep >> 6) & 3; - reg = (*codep >> 3) & 7; - rm = *codep & 7; - - if (dp->name == NULL && dp->bytemode1 == FLOATCODE) - { - dofloat (); - } - else - { - if (dp->name == NULL) - dp = &grps[dp->bytemode1][reg]; - - putop (dp->name); - - obufp = op1out; - op_ad = 2; - if (dp->op1) - (*dp->op1)(dp->bytemode1); - - obufp = op2out; - op_ad = 1; - if (dp->op2) - (*dp->op2)(dp->bytemode2); - - obufp = op3out; - op_ad = 0; - if (dp->op3) - (*dp->op3)(dp->bytemode3); - } - - obufp = obuf + strlen (obuf); - for (i = strlen (obuf); i < 6; i++) - oappend (" "); - oappend (" "); - (*info->fprintf_func) (info->stream, "%s", obuf); - - /* enter instruction is printed with operands in the - * same order as the intel book; everything else - * is printed in reverse order - */ - if (enter_instruction) - { - first = op1out; - second = op2out; - third = op3out; - op_ad = op_index[0]; - op_index[0] = op_index[2]; - op_index[2] = op_ad; - } - else - { - first = op3out; - second = op2out; - third = op1out; - } - needcomma = 0; - if (*first) - { - if (op_index[0] != -1) - (*info->print_address_func) (op_address[op_index[0]], info); - else - (*info->fprintf_func) (info->stream, "%s", first); - needcomma = 1; - } - if (*second) - { - if (needcomma) - (*info->fprintf_func) (info->stream, ","); - if (op_index[1] != -1) - (*info->print_address_func) (op_address[op_index[1]], info); - else - (*info->fprintf_func) (info->stream, "%s", second); - needcomma = 1; - } - if (*third) - { - if (needcomma) - (*info->fprintf_func) (info->stream, ","); - if (op_index[2] != -1) - (*info->print_address_func) (op_address[op_index[2]], info); - else - (*info->fprintf_func) (info->stream, "%s", third); - } - return (codep - inbuf); -} - -char *float_mem[] = { - /* d8 */ - "fadds", - "fmuls", - "fcoms", - "fcomps", - "fsubs", - "fsubrs", - "fdivs", - "fdivrs", - /* d9 */ - "flds", - "(bad)", - "fsts", - "fstps", - "fldenv", - "fldcw", - "fNstenv", - "fNstcw", - /* da */ - "fiaddl", - "fimull", - "ficoml", - "ficompl", - "fisubl", - "fisubrl", - "fidivl", - "fidivrl", - /* db */ - "fildl", - "(bad)", - "fistl", - "fistpl", - "(bad)", - "fldt", - "(bad)", - "fstpt", - /* dc */ - "faddl", - "fmull", - "fcoml", - "fcompl", - "fsubl", - "fsubrl", - "fdivl", - "fdivrl", - /* dd */ - "fldl", - "(bad)", - "fstl", - "fstpl", - "frstor", - "(bad)", - "fNsave", - "fNstsw", - /* de */ - "fiadd", - "fimul", - "ficom", - "ficomp", - "fisub", - "fisubr", - "fidiv", - "fidivr", - /* df */ - "fild", - "(bad)", - "fist", - "fistp", - "fbld", - "fildll", - "fbstp", - "fistpll", -}; - -#define ST OP_ST, 0 -#define STi OP_STi, 0 -int OP_ST(), OP_STi(); - -#define FGRPd9_2 NULL, NULL, 0 -#define FGRPd9_4 NULL, NULL, 1 -#define FGRPd9_5 NULL, NULL, 2 -#define FGRPd9_6 NULL, NULL, 3 -#define FGRPd9_7 NULL, NULL, 4 -#define FGRPda_5 NULL, NULL, 5 -#define FGRPdb_4 NULL, NULL, 6 -#define FGRPde_3 NULL, NULL, 7 -#define FGRPdf_4 NULL, NULL, 8 - -struct dis386 float_reg[][8] = { - /* d8 */ - { - { "fadd", ST, STi }, - { "fmul", ST, STi }, - { "fcom", STi }, - { "fcomp", STi }, - { "fsub", ST, STi }, - { "fsubr", ST, STi }, - { "fdiv", ST, STi }, - { "fdivr", ST, STi }, - }, - /* d9 */ - { - { "fld", STi }, - { "fxch", STi }, - { FGRPd9_2 }, - { "(bad)" }, - { FGRPd9_4 }, - { FGRPd9_5 }, - { FGRPd9_6 }, - { FGRPd9_7 }, - }, - /* da */ - { - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { FGRPda_5 }, - { "(bad)" }, - { "(bad)" }, - }, - /* db */ - { - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { FGRPdb_4 }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - }, - /* dc */ - { - { "fadd", STi, ST }, - { "fmul", STi, ST }, - { "(bad)" }, - { "(bad)" }, - { "fsub", STi, ST }, - { "fsubr", STi, ST }, - { "fdiv", STi, ST }, - { "fdivr", STi, ST }, - }, - /* dd */ - { - { "ffree", STi }, - { "(bad)" }, - { "fst", STi }, - { "fstp", STi }, - { "fucom", STi }, - { "fucomp", STi }, - { "(bad)" }, - { "(bad)" }, - }, - /* de */ - { - { "faddp", STi, ST }, - { "fmulp", STi, ST }, - { "(bad)" }, - { FGRPde_3 }, - { "fsubp", STi, ST }, - { "fsubrp", STi, ST }, - { "fdivp", STi, ST }, - { "fdivrp", STi, ST }, - }, - /* df */ - { - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { FGRPdf_4 }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - }, -}; - - -char *fgrps[][8] = { - /* d9_2 0 */ - { - "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, - - /* d9_4 1 */ - { - "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", - }, - - /* d9_5 2 */ - { - "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", - }, - - /* d9_6 3 */ - { - "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", - }, - - /* d9_7 4 */ - { - "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", - }, - - /* da_5 5 */ - { - "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, - - /* db_4 6 */ - { - "feni(287 only)","fdisi(287 only)","fNclex","fNinit", - "fNsetpm(287 only)","(bad)","(bad)","(bad)", - }, - - /* de_3 7 */ - { - "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, - - /* df_4 8 */ - { - "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, -}; - -static void -dofloat () -{ - struct dis386 *dp; - unsigned char floatop; - - floatop = codep[-1]; - - if (mod != 3) - { - putop (float_mem[(floatop - 0xd8) * 8 + reg]); - obufp = op1out; - OP_E (v_mode); - return; - } - codep++; - - dp = &float_reg[floatop - 0xd8][reg]; - if (dp->name == NULL) - { - putop (fgrps[dp->bytemode1][rm]); - /* instruction fnstsw is only one with strange arg */ - if (floatop == 0xdf - && FETCH_DATA (the_info, codep + 1) - && *codep == 0xe0) - strcpy (op1out, "%eax"); - } - else - { - putop (dp->name); - obufp = op1out; - if (dp->op1) - (*dp->op1)(dp->bytemode1); - obufp = op2out; - if (dp->op2) - (*dp->op2)(dp->bytemode2); - } -} - -/* ARGSUSED */ -int -OP_ST (ignore) - int ignore; -{ - oappend ("%st"); - return (0); -} - -/* ARGSUSED */ -int -OP_STi (ignore) - int ignore; -{ - sprintf (scratchbuf, "%%st(%d)", rm); - oappend (scratchbuf); - return (0); -} - - -/* capital letters in template are macros */ -static void -putop (template) - char *template; -{ - char *p; - - for (p = template; *p; p++) - { - switch (*p) - { - default: - *obufp++ = *p; - break; - case 'C': /* For jcxz/jecxz */ - if (aflag == 0) - *obufp++ = 'e'; - break; - case 'N': - if ((prefixes & PREFIX_FWAIT) == 0) - *obufp++ = 'n'; - break; - case 'S': - /* operand size flag */ - if (dflag) - *obufp++ = 'l'; - else - *obufp++ = 'w'; - break; - } - } - *obufp = 0; -} - -static void -oappend (s) - char *s; -{ - strcpy (obufp, s); - obufp += strlen (s); - *obufp = 0; -} - -static void -append_prefix () -{ - if (prefixes & PREFIX_CS) - oappend ("%cs:"); - if (prefixes & PREFIX_DS) - oappend ("%ds:"); - if (prefixes & PREFIX_SS) - oappend ("%ss:"); - if (prefixes & PREFIX_ES) - oappend ("%es:"); - if (prefixes & PREFIX_FS) - oappend ("%fs:"); - if (prefixes & PREFIX_GS) - oappend ("%gs:"); -} - -int -OP_indirE (bytemode) - int bytemode; -{ - oappend ("*"); - OP_E (bytemode); - return (0); -} - -int -OP_E (bytemode) - int bytemode; -{ - int disp; - int havesib; - int base; - int index; - int scale; - int havebase; - - /* skip mod/rm byte */ - codep++; - - havesib = 0; - havebase = 0; - disp = 0; - - if (mod == 3) - { - switch (bytemode) - { - case b_mode: - oappend (names8[rm]); - break; - case w_mode: - oappend (names16[rm]); - break; - case v_mode: - if (dflag) - oappend (names32[rm]); - else - oappend (names16[rm]); - break; - default: - oappend (""); - break; - } - return (0); - } - - append_prefix (); - if (rm == 4) - { - havesib = 1; - havebase = 1; - FETCH_DATA (the_info, codep + 1); - scale = (*codep >> 6) & 3; - index = (*codep >> 3) & 7; - base = *codep & 7; - codep++; - } - - switch (mod) - { - case 0: - switch (rm) - { - case 4: - /* implies havesib and havebase */ - if (base == 5) { - havebase = 0; - disp = get32 (); - } - break; - case 5: - disp = get32 (); - break; - default: - havebase = 1; - base = rm; - break; - } - break; - case 1: - FETCH_DATA (the_info, codep + 1); - disp = *(char *)codep++; - if (rm != 4) - { - havebase = 1; - base = rm; - } - break; - case 2: - disp = get32 (); - if (rm != 4) - { - havebase = 1; - base = rm; - } - break; - } - - if (mod != 0 || rm == 5 || (havesib && base == 5)) - { - sprintf (scratchbuf, "0x%x", disp); - oappend (scratchbuf); - } - - if (havebase || havesib) - { - oappend ("("); - if (havebase) - oappend (names32[base]); - if (havesib) - { - if (index != 4) - { - sprintf (scratchbuf, ",%s", names32[index]); - oappend (scratchbuf); - } - sprintf (scratchbuf, ",%d", 1 << scale); - oappend (scratchbuf); - } - oappend (")"); - } - return (0); -} - -int -OP_G (bytemode) - int bytemode; -{ - switch (bytemode) - { - case b_mode: - oappend (names8[reg]); - break; - case w_mode: - oappend (names16[reg]); - break; - case d_mode: - oappend (names32[reg]); - break; - case v_mode: - if (dflag) - oappend (names32[reg]); - else - oappend (names16[reg]); - break; - default: - oappend (""); - break; - } - return (0); -} - -static int -get32 () -{ - int x = 0; - - FETCH_DATA (the_info, codep + 4); - x = *codep++ & 0xff; - x |= (*codep++ & 0xff) << 8; - x |= (*codep++ & 0xff) << 16; - x |= (*codep++ & 0xff) << 24; - return (x); -} - -static int -get16 () -{ - int x = 0; - - FETCH_DATA (the_info, codep + 2); - x = *codep++ & 0xff; - x |= (*codep++ & 0xff) << 8; - return (x); -} - -static void -set_op (op) - int op; -{ - op_index[op_ad] = op_ad; - op_address[op_ad] = op; -} - -int -OP_REG (code) - int code; -{ - char *s; - - switch (code) - { - case indir_dx_reg: s = "(%dx)"; break; - case ax_reg: case cx_reg: case dx_reg: case bx_reg: - case sp_reg: case bp_reg: case si_reg: case di_reg: - s = names16[code - ax_reg]; - break; - case es_reg: case ss_reg: case cs_reg: - case ds_reg: case fs_reg: case gs_reg: - s = names_seg[code - es_reg]; - break; - case al_reg: case ah_reg: case cl_reg: case ch_reg: - case dl_reg: case dh_reg: case bl_reg: case bh_reg: - s = names8[code - al_reg]; - break; - case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: - case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: - if (dflag) - s = names32[code - eAX_reg]; - else - s = names16[code - eAX_reg]; - break; - default: - s = ""; - break; - } - oappend (s); - return (0); -} - -int -OP_I (bytemode) - int bytemode; -{ - int op; - - switch (bytemode) - { - case b_mode: - FETCH_DATA (the_info, codep + 1); - op = *codep++ & 0xff; - break; - case v_mode: - if (dflag) - op = get32 (); - else - op = get16 (); - break; - case w_mode: - op = get16 (); - break; - default: - oappend (""); - return (0); - } - sprintf (scratchbuf, "$0x%x", op); - oappend (scratchbuf); - return (0); -} - -int -OP_sI (bytemode) - int bytemode; -{ - int op; - - switch (bytemode) - { - case b_mode: - FETCH_DATA (the_info, codep + 1); - op = *(char *)codep++; - break; - case v_mode: - if (dflag) - op = get32 (); - else - op = (short)get16(); - break; - case w_mode: - op = (short)get16 (); - break; - default: - oappend (""); - return (0); - } - sprintf (scratchbuf, "$0x%x", op); - oappend (scratchbuf); - return (0); -} - -int -OP_J (bytemode) - int bytemode; -{ - int disp; - int mask = -1; - - switch (bytemode) - { - case b_mode: - FETCH_DATA (the_info, codep + 1); - disp = *(char *)codep++; - break; - case v_mode: - if (dflag) - disp = get32 (); - else - { - disp = (short)get16 (); - /* for some reason, a data16 prefix on a jump instruction - means that the pc is masked to 16 bits after the - displacement is added! */ - mask = 0xffff; - } - break; - default: - oappend (""); - return (0); - } - disp = (start_pc + codep - start_codep + disp) & mask; - set_op (disp); - sprintf (scratchbuf, "0x%x", disp); - oappend (scratchbuf); - return (0); -} - -/* ARGSUSED */ -int -OP_SEG (dummy) - int dummy; -{ - static char *sreg[] = { - "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", - }; - - oappend (sreg[reg]); - return (0); -} - -int -OP_DIR (size) - int size; -{ - int seg, offset; - - switch (size) - { - case lptr: - if (aflag) - { - offset = get32 (); - seg = get16 (); - } - else - { - offset = get16 (); - seg = get16 (); - } - sprintf (scratchbuf, "0x%x,0x%x", seg, offset); - oappend (scratchbuf); - break; - case v_mode: - if (aflag) - offset = get32 (); - else - offset = (short)get16 (); - - offset = start_pc + codep - start_codep + offset; - set_op (offset); - sprintf (scratchbuf, "0x%x", offset); - oappend (scratchbuf); - break; - default: - oappend (""); - break; - } - return (0); -} - -/* ARGSUSED */ -int -OP_OFF (bytemode) - int bytemode; -{ - int off; - - if (aflag) - off = get32 (); - else - off = get16 (); - - sprintf (scratchbuf, "0x%x", off); - oappend (scratchbuf); - return (0); -} - -/* ARGSUSED */ -int -OP_ESDI (dummy) - int dummy; -{ - oappend ("%es:("); - oappend (aflag ? "%edi" : "%di"); - oappend (")"); - return (0); -} - -/* ARGSUSED */ -int -OP_DSSI (dummy) - int dummy; -{ - oappend ("%ds:("); - oappend (aflag ? "%esi" : "%si"); - oappend (")"); - return (0); -} - -/* ARGSUSED */ -int -OP_ONE (dummy) - int dummy; -{ - oappend ("1"); - return (0); -} - -/* ARGSUSED */ -int -OP_C (dummy) - int dummy; -{ - codep++; /* skip mod/rm */ - sprintf (scratchbuf, "%%cr%d", reg); - oappend (scratchbuf); - return (0); -} - -/* ARGSUSED */ -int -OP_D (dummy) - int dummy; -{ - codep++; /* skip mod/rm */ - sprintf (scratchbuf, "%%db%d", reg); - oappend (scratchbuf); - return (0); -} - -/* ARGSUSED */ -int -OP_T (dummy) - int dummy; -{ - codep++; /* skip mod/rm */ - sprintf (scratchbuf, "%%tr%d", reg); - oappend (scratchbuf); - return (0); -} - -int -OP_rm (bytemode) - int bytemode; -{ - switch (bytemode) - { - case d_mode: - oappend (names32[rm]); - break; - case w_mode: - oappend (names16[rm]); - break; - } - return (0); -} diff --git a/gnu/usr.bin/gdb/gdb/i386-pinsn.c b/gnu/usr.bin/gdb/gdb/i386-pinsn.c deleted file mode 100644 index c11ee49..0000000 --- a/gnu/usr.bin/gdb/gdb/i386-pinsn.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Print i386 instructions for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 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. */ - -#include "defs.h" -#include "dis-asm.h" - - -/* Print the instruction at address MEMADDR in debugged memory, - on STREAM. Returns length of the instruction, in bytes. */ - -int -print_insn (memaddr, stream) - CORE_ADDR memaddr; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO(info, stream); - - return print_insn_i386 (memaddr, &info); -} diff --git a/gnu/usr.bin/gdb/gdb/i386-tdep.c b/gnu/usr.bin/gdb/gdb/i386-tdep.c deleted file mode 100644 index 2247dd1..0000000 --- a/gnu/usr.bin/gdb/gdb/i386-tdep.c +++ /dev/null @@ -1,668 +0,0 @@ -/* Intel 386 target-dependent stuff. - Copyright (C) 1988, 1989, 1991, 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. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "gdbcore.h" -#include "target.h" -#include "floatformat.h" -#include "symtab.h" - -static long -i386_get_frame_setup PARAMS ((int)); - -static void -i386_follow_jump PARAMS ((void)); - -static void -codestream_read PARAMS ((unsigned char *, int)); - -static void -codestream_seek PARAMS ((int)); - -static unsigned char -codestream_fill PARAMS ((int)); - -/* helper functions for tm-i386.h */ - -/* 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 - sizeof(int) long). In cases where the code section size happened to - be a non-integral number of buffers long, attempting to read the last - buffer would fail. Simply using target_read_memory and ignoring errors, - rather than read_memory, is not the correct solution, since legitimate - access errors would then be totally ignored. To properly handle this - situation and continue to use buffering would require that this code - be able to determine the minimum code section size granularity (not the - alignment of the section itself, since the actual failing case that - pointed out this problem had a section alignment of 4 but was not a - multiple of 4 bytes long), on a target by target basis, and then - adjust it's buffer size accordingly. This is messy, but potentially - feasible. It probably needs the bfd library's help and support. For - now, the buffer size is set to 1. (FIXME -fnf) */ - -#define CODESTREAM_BUFSIZ 1 /* Was sizeof(int), see note above. */ -static CORE_ADDR codestream_next_addr; -static CORE_ADDR codestream_addr; -static unsigned char codestream_buf[CODESTREAM_BUFSIZ]; -static int codestream_off; -static int codestream_cnt; - -#define codestream_tell() (codestream_addr + codestream_off) -#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 char -codestream_fill (peek_flag) - int peek_flag; -{ - codestream_addr = codestream_next_addr; - codestream_next_addr += CODESTREAM_BUFSIZ; - codestream_off = 0; - codestream_cnt = CODESTREAM_BUFSIZ; - read_memory (codestream_addr, (char *) codestream_buf, CODESTREAM_BUFSIZ); - - if (peek_flag) - return (codestream_peek()); - else - return (codestream_get()); -} - -static void -codestream_seek (place) - int place; -{ - codestream_next_addr = place / CODESTREAM_BUFSIZ; - codestream_next_addr *= CODESTREAM_BUFSIZ; - codestream_cnt = 0; - codestream_fill (1); - while (codestream_tell() != place) - codestream_get (); -} - -static void -codestream_read (buf, count) - unsigned char *buf; - int count; -{ - unsigned char *p; - int i; - p = buf; - for (i = 0; i < count; i++) - *p++ = codestream_get (); -} - -/* next instruction is a jump, move to target */ - -static void -i386_follow_jump () -{ - unsigned char buf[4]; - long delta; - - int data16; - CORE_ADDR pos; - - pos = codestream_tell (); - - data16 = 0; - if (codestream_peek () == 0x66) - { - codestream_get (); - data16 = 1; - } - - switch (codestream_get ()) - { - case 0xe9: - /* relative jump: if data16 == 0, disp32, else disp16 */ - if (data16) - { - codestream_read (buf, 2); - delta = extract_signed_integer (buf, 2); - - /* include size of jmp inst (including the 0x66 prefix). */ - pos += delta + 4; - } - else - { - codestream_read (buf, 4); - delta = extract_signed_integer (buf, 4); - - pos += delta + 5; - } - break; - case 0xeb: - /* relative jump, disp8 (ignore data16) */ - codestream_read (buf, 1); - /* Sign-extend it. */ - delta = extract_signed_integer (buf, 1); - - pos += delta + 2; - break; - } - codestream_seek (pos); -} - -/* - * find & return amound 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 -i386_get_frame_setup (pc) - int pc; -{ - unsigned char op; - - codestream_seek (pc); - - i386_follow_jump (); - - op = codestream_get (); - - if (op == 0x58) /* popl %eax */ - { - /* - * this function must start with - * - * popl %eax 0x58 - * xchgl %eax, (%esp) 0x87 0x04 0x24 - * or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00 - * - * (the system 5 compiler puts out the second xchg - * inst, and the assembler doesn't try to optimize it, - * so the 'sib' form gets generated) - * - * this sequence is used to get the address of the return - * buffer for a function that returns a structure - */ - int pos; - unsigned char buf[4]; - static unsigned char proto1[3] = { 0x87,0x04,0x24 }; - static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 }; - pos = codestream_tell (); - codestream_read (buf, 4); - if (memcmp (buf, proto1, 3) == 0) - pos += 3; - else if (memcmp (buf, proto2, 4) == 0) - pos += 4; - - codestream_seek (pos); - op = codestream_get (); /* update next opcode */ - } - - if (op == 0x55) /* pushl %ebp */ - { - /* check for movl %esp, %ebp - can be written two ways */ - switch (codestream_get ()) - { - case 0x8b: - if (codestream_get () != 0xec) - return (-1); - break; - case 0x89: - if (codestream_get () != 0xe5) - return (-1); - break; - default: - return (-1); - } - /* check for stack adjustment - * - * subl $XXX, %esp - * - * note: you can't subtract a 16 bit immediate - * from a 32 bit reg, so we don't have to worry - * about a data16 prefix - */ - op = codestream_peek (); - if (op == 0x83) - { - /* subl with 8 bit immed */ - codestream_get (); - if (codestream_get () != 0xec) - /* Some instruction starting with 0x83 other than subl. */ - { - codestream_seek (codestream_tell () - 2); - return 0; - } - /* subl with signed byte immediate - * (though it wouldn't make sense to be negative) - */ - return (codestream_get()); - } - else if (op == 0x81) - { - char buf[4]; - /* Maybe it is subl with 32 bit immedediate. */ - codestream_get(); - if (codestream_get () != 0xec) - /* Some instruction starting with 0x81 other than subl. */ - { - codestream_seek (codestream_tell () - 2); - return 0; - } - /* It is subl with 32 bit immediate. */ - codestream_read ((unsigned char *)buf, 4); - return extract_signed_integer (buf, 4); - } - else - { - return (0); - } - } - else if (op == 0xc8) - { - char buf[2]; - /* enter instruction: arg is 16 bit unsigned immed */ - codestream_read ((unsigned char *)buf, 2); - codestream_get (); /* flush final byte of enter instruction */ - return extract_unsigned_integer (buf, 2); - } - return (-1); -} - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ - -int -i386_frame_num_args (fi) - struct frame_info *fi; -{ -#if 1 - return -1; -#else - /* This loses because not only might the compiler not be popping the - args right after the function call, it might be popping args from both - this call and a previous one, and we would say there are more args - than there really are. */ - - int retpc; - unsigned char op; - struct frame_info *pfi; - - /* on the 386, the instruction following the call could be: - popl %ecx - one arg - addl $imm, %esp - imm/4 args; imm may be 8 or 32 bits - anything else - zero args */ - - int frameless; - - FRAMELESS_FUNCTION_INVOCATION (fi, frameless); - if (frameless) - /* In the absence of a frame pointer, GDB doesn't get correct values - for nameless arguments. Return -1, so it doesn't print any - nameless arguments. */ - return -1; - - pfi = get_prev_frame_info (fi); - if (pfi == 0) - { - /* Note: this can happen if we are looking at the frame for - main, because FRAME_CHAIN_VALID won't let us go into - start. If we have debugging symbols, that's not really - a big deal; it just means it will only show as many arguments - to main as are declared. */ - return -1; - } - else - { - retpc = pfi->pc; - op = read_memory_integer (retpc, 1); - if (op == 0x59) - /* pop %ecx */ - return 1; - else if (op == 0x83) - { - op = read_memory_integer (retpc+1, 1); - if (op == 0xc4) - /* addl $, %esp */ - return (read_memory_integer (retpc+2,1)&0xff)/4; - else - return 0; - } - else if (op == 0x81) - { /* add with 32 bit immediate */ - op = read_memory_integer (retpc+1, 1); - if (op == 0xc4) - /* addl $, %esp */ - return read_memory_integer (retpc+2, 4) / 4; - else - return 0; - } - else - { - return 0; - } - } -#endif -} - -/* - * parse the first few instructions of the function to see - * what registers were stored. - * - * We handle these cases: - * - * The startup sequence can be at the start of the function, - * or the function can start with a branch to startup code at the end. - * - * %ebp can be set up with either the 'enter' instruction, or - * 'pushl %ebp, movl %esp, %ebp' (enter is too slow to be useful, - * but was once used in the sys5 compiler) - * - * Local space is allocated just below the saved %ebp by either the - * 'enter' instruction, or by 'subl $, %esp'. 'enter' has - * a 16 bit unsigned argument for space to allocate, and the - * 'addl' instruction could have either a signed byte, or - * 32 bit immediate. - * - * Next, the registers used by this function are pushed. In - * the sys5 compiler they will always be in the order: %edi, %esi, %ebx - * (and sometimes a harmless bug causes it to also save but not restore %eax); - * however, the code below is willing to see the pushes in any order, - * and will handle up to 8 of them. - * - * If the setup sequence is at the end of the function, then the - * next instruction will be a branch back to the start. - */ - -void -i386_frame_find_saved_regs (fip, fsrp) - struct frame_info *fip; - struct frame_saved_regs *fsrp; -{ - long locals; - unsigned char op; - CORE_ADDR dummy_bottom; - CORE_ADDR adr; - int i; - - 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 = i386_get_frame_setup (get_pc_function_start (fip->pc)); - - if (locals >= 0) - { - adr = fip->frame - 4 - locals; - for (i = 0; i < 8; i++) - { - op = codestream_get (); - if (op < 0x50 || op > 0x57) - break; -#ifdef I386_REGNO_TO_SYMMETRY - /* Dynix uses different internal numbering. Ick. */ - fsrp->regs[I386_REGNO_TO_SYMMETRY(op - 0x50)] = adr; -#else - fsrp->regs[op - 0x50] = adr; -#endif - adr -= 4; - } - } - - fsrp->regs[PC_REGNUM] = fip->frame + 4; - fsrp->regs[FP_REGNUM] = fip->frame; -} - -/* return pc of first real instruction */ - -int -i386_skip_prologue (pc) - int pc; -{ - unsigned char op; - int i; - static unsigned char pic_pat[6] = { 0xe8, 0, 0, 0, 0, /* call 0x0 */ - 0x5b, /* popl %ebx */ - }; - CORE_ADDR pos; - - if (i386_get_frame_setup (pc) < 0) - return (pc); - - /* found valid frame setup - codestream now points to - * start of push instructions for saving registers - */ - - /* skip over register saves */ - for (i = 0; i < 8; i++) - { - op = codestream_peek (); - /* break if not pushl inst */ - if (op < 0x50 || op > 0x57) - break; - codestream_get (); - } - - /* The native cc on SVR4 in -K PIC mode inserts the following code to get - the address of the global offset table (GOT) into register %ebx. - call 0x0 - popl %ebx - movl %ebx,x(%ebp) (optional) - addl y,%ebx - This code is with the rest of the prologue (at the end of the - function), so we have to skip it to get to the first real - instruction at the start of the function. */ - - pos = codestream_tell (); - for (i = 0; i < 6; i++) - { - op = codestream_get (); - if (pic_pat [i] != op) - break; - } - if (i == 6) - { - unsigned char buf[4]; - long delta = 6; - - op = codestream_get (); - if (op == 0x89) /* movl %ebx, x(%ebp) */ - { - op = codestream_get (); - if (op == 0x5d) /* one byte offset from %ebp */ - { - delta += 3; - codestream_read (buf, 1); - } - else if (op == 0x9d) /* four byte offset from %ebp */ - { - delta += 6; - codestream_read (buf, 4); - } - else /* unexpected instruction */ - delta = -1; - op = codestream_get (); - } - /* addl y,%ebx */ - if (delta > 0 && op == 0x81 && codestream_get () == 0xc3) - { - pos += delta + 6; - } - } - codestream_seek (pos); - - i386_follow_jump (); - - return (codestream_tell ()); -} - -void -i386_push_dummy_frame () -{ - CORE_ADDR sp = read_register (SP_REGNUM); - int regnum; - char regbuf[MAX_REGISTER_RAW_SIZE]; - - sp = push_word (sp, read_register (PC_REGNUM)); - sp = push_word (sp, read_register (FP_REGNUM)); - 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)); - } - write_register (SP_REGNUM, sp); -} - -void -i386_pop_frame () -{ - FRAME frame = get_current_frame (); - CORE_ADDR fp; - int regnum; - struct frame_saved_regs fsr; - struct frame_info *fi; - char regbuf[MAX_REGISTER_RAW_SIZE]; - - fi = get_frame_info (frame); - fp = fi->frame; - get_frame_saved_regs (fi, &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 (); - set_current_frame ( create_new_frame (read_register (FP_REGNUM), - read_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 */ - -#ifdef I386_AIX_TARGET -/* On AIX, floating point values are returned in floating point registers. */ - -void -i386_extract_return_value(type, regbuf, valbuf) - struct type *type; - char regbuf[REGISTER_BYTES]; - char *valbuf; -{ - if (TYPE_CODE_FLT == TYPE_CODE(type)) - { - double d; - /* 387 %st(0), gcc uses this */ - floatformat_to_double (&floatformat_i387_ext, - ®buf[REGISTER_BYTE(FP0_REGNUM)], - &d); - store_floating (valbuf, TYPE_LENGTH (type), d); - } - else - { - memcpy (valbuf, regbuf, TYPE_LENGTH (type)); - } -} -#endif /* I386_AIX_TARGET */ - -#ifdef I386V4_SIGTRAMP_SAVED_PC -/* Get saved user PC for sigtramp from the pushed ucontext on the stack - for all three variants of SVR4 sigtramps. */ - -CORE_ADDR -i386v4_sigtramp_saved_pc (frame) - FRAME frame; -{ - CORE_ADDR saved_pc_offset = 4; - char *name = NULL; - - find_pc_partial_function (frame->pc, &name, - (CORE_ADDR *)NULL,(CORE_ADDR *)NULL); - if (name) - { - if (STREQ (name, "_sigreturn")) - saved_pc_offset = 132 + 14 * 4; - else if (STREQ (name, "_sigacthandler")) - saved_pc_offset = 80 + 14 * 4; - else if (STREQ (name, "sigvechandler")) - saved_pc_offset = 120 + 14 * 4; - } - - if (frame->next) - return read_memory_integer (frame->next->frame + saved_pc_offset, 4); - return read_memory_integer (read_register (SP_REGNUM) + saved_pc_offset, 4); -} -#endif /* I386V4_SIGTRAMP_SAVED_PC */ diff --git a/gnu/usr.bin/gdb/gdb/i386freebsd.h b/gnu/usr.bin/gdb/gdb/i386freebsd.h new file mode 100644 index 0000000..af011311 --- /dev/null +++ b/gnu/usr.bin/gdb/gdb/i386freebsd.h @@ -0,0 +1,23 @@ +/* Intel 386 running any FreeBSD Unix */ + +#include +#include + +#define NBPG PAGE_SIZE +#define HOST_PAGE_SIZE NBPG +#define HOST_MACHINE_ARCH bfd_arch_i386 +#define HOST_TEXT_START_ADDR USRTEXT + +/* Jolitz suggested defining HOST_STACK_END_ADDR to + (u.u_kproc.kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ), which should work on + both BSDI and 386BSD, but that is believed not to work for BSD 4.4. */ + +/* This seems to be the right thing for FreeBSD and BSDI */ +#define HOST_STACK_END_ADDR USRSTACK + +/* BSDI defines this too (PST) */ +#define HOST_DATA_START_ADDR ((bfd_vma)u.u_kproc.kp_eproc.e_vm.vm_daddr) + +#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \ + ((core_bfd)->tdata.trad_core_data->u.u_sig) +#define u_comm u_kproc.kp_proc.p_comm diff --git a/gnu/usr.bin/gdb/gdb/ieee.h b/gnu/usr.bin/gdb/gdb/ieee.h deleted file mode 100644 index 22cd140..0000000 --- a/gnu/usr.bin/gdb/gdb/ieee.h +++ /dev/null @@ -1,132 +0,0 @@ -/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file - Contributed by Cygnus Support. */ - -#define N_W_VARIABLES 8 -#define Module_Beginning 0xe0 - -typedef struct ieee_module { - char *processor; - char *module_name; -} ieee_module_begin_type; - -#define Address_Descriptor 0xec -typedef struct ieee_address { -bfd_vma number_of_bits_mau; - bfd_vma number_of_maus_in_address; - - unsigned char byte_order; -#define IEEE_LITTLE 0xcc -#define IEEE_BIG 0xcd -} ieee_address_descriptor_type; - -typedef union ieee_w_variable { - file_ptr offset[N_W_VARIABLES]; - struct { - file_ptr extension_record; - file_ptr environmental_record; - file_ptr section_part; - file_ptr external_part; - file_ptr debug_information_part; - file_ptr data_part; - file_ptr trailer_part; - file_ptr me_record; - } r; -} ieee_w_variable_type; - - - - - -typedef enum ieee_record -{ - ieee_number_start_enum = 0x00, - ieee_number_end_enum=0x7f, - ieee_number_repeat_start_enum = 0x80, - ieee_number_repeat_end_enum = 0x88, - ieee_number_repeat_4_enum = 0x84, - ieee_number_repeat_3_enum = 0x83, - ieee_number_repeat_2_enum = 0x82, - ieee_number_repeat_1_enum = 0x81, - ieee_module_beginning_enum = 0xe0, - ieee_module_end_enum = 0xe1, - ieee_extension_length_1_enum = 0xde, - ieee_extension_length_2_enum = 0xdf, - ieee_section_type_enum = 0xe6, - ieee_section_alignment_enum = 0xe7, - ieee_external_symbol_enum = 0xe8, - ieee_attribute_record_enum = 0xf1c9, - ieee_comma = 0x90, - ieee_external_reference_enum = 0xe9, - ieee_set_current_section_enum = 0xe5, - ieee_address_descriptor_enum = 0xec, - ieee_load_constant_bytes_enum = 0xed, - ieee_load_with_relocation_enum = 0xe4, - - ieee_variable_A_enum = 0xc1, - ieee_variable_B_enum = 0xc2, - ieee_variable_C_enum = 0xc3, - ieee_variable_D_enum = 0xc4, - ieee_variable_E_enum = 0xc5, - ieee_variable_F_enum = 0xc6, - ieee_variable_G_enum = 0xc7, - ieee_variable_H_enum = 0xc8, - ieee_variable_I_enum = 0xc9, - ieee_variable_J_enum = 0xca, - ieee_variable_K_enum = 0xcb, - ieee_variable_L_enum = 0xcc, - ieee_variable_M_enum = 0xcd, - ieee_variable_N_enum = 0xce, - ieee_variable_O_enum = 0xcf, - ieee_variable_P_enum = 0xd0, - ieee_variable_Q_enum = 0xd1, - ieee_variable_R_enum = 0xd2, - ieee_variable_S_enum = 0xd3, - ieee_variable_T_enum = 0xd4, - ieee_variable_U_enum = 0xd5, - ieee_variable_V_enum = 0xd6, - ieee_variable_W_enum = 0xd7, - ieee_variable_X_enum = 0xd8, - ieee_variable_Y_enum = 0xd9, - ieee_variable_Z_enum = 0xda, - ieee_function_plus_enum = 0xa5, - ieee_function_minus_enum = 0xa6, - ieee_function_signed_open_b_enum = 0xba, - ieee_function_signed_close_b_enum = 0xbb, - - ieee_function_unsigned_open_b_enum = 0xbc, - ieee_function_unsigned_close_b_enum = 0xbd, - - ieee_function_either_open_b_enum = 0xbe, - ieee_function_either_close_b_enum = 0xbf, - ieee_record_seperator_enum = 0xdb, - - ieee_e2_first_byte_enum = 0xe2, - ieee_section_size_enum = 0xe2d3, - ieee_physical_region_size_enum = 0xe2c1, - ieee_region_base_address_enum = 0xe2c2, - ieee_mau_size_enum = 0xe2c6, - ieee_m_value_enum = 0xe2cd, - ieee_section_base_address_enum = 0xe2cc, - ieee_section_offset_enum = 0xe2d2, - ieee_value_starting_address_enum = 0xe2c7, - ieee_assign_value_to_variable_enum = 0xe2d7, - ieee_set_current_pc_enum = 0xe2d0, - ieee_value_record_enum = 0xe2c9, -ieee_nn_record = 0xf0, - ieee_weak_external_reference_enum= 0xf4, - ieee_repeat_data_enum = 0xf7 -} ieee_record_enum_type; - - -typedef struct ieee_section { - unsigned int section_index; - unsigned int section_type; - char *section_name; - unsigned int parent_section_index; - unsigned int sibling_section_index; - unsigned int context_index; -} ieee_section_type; -#define IEEE_REFERENCE_BASE 11 -#define IEEE_PUBLIC_BASE 32 -#define IEEE_SECTION_NUMBER_BASE 1 - diff --git a/gnu/usr.bin/gdb/gdb/infcmd.c b/gnu/usr.bin/gdb/gdb/infcmd.c deleted file mode 100644 index d0404e1..0000000 --- a/gnu/usr.bin/gdb/gdb/infcmd.c +++ /dev/null @@ -1,1384 +0,0 @@ -/* Memory-access and commands for "inferior" (child) process, for GDB. - Copyright 1986, 1987, 1988, 1989, 1991, 1992 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 "defs.h" -#include -#include -#include -#include "symtab.h" -#include "gdbtypes.h" -#include "frame.h" -#include "inferior.h" -#include "environ.h" -#include "value.h" -#include "gdbcmd.h" -#include "gdbcore.h" -#include "target.h" -#include "language.h" - -static void -continue_command PARAMS ((char *, int)); - -static void -until_next_command PARAMS ((int)); - -static void -until_command PARAMS ((char *, int)); - -static void -path_info PARAMS ((char *, int)); - -static void -path_command PARAMS ((char *, int)); - -static void -unset_command PARAMS ((char *, int)); - -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)); - -static void -do_registers_info PARAMS ((int, int)); - -static void -unset_environment_command PARAMS ((char *, int)); - -static void -set_environment_command PARAMS ((char *, int)); - -static void -environment_info PARAMS ((char *, int)); - -static void -program_info PARAMS ((char *, int)); - -static void -finish_command PARAMS ((char *, int)); - -static void -signal_command PARAMS ((char *, int)); - -static void -jump_command PARAMS ((char *, int)); - -static void -step_1 PARAMS ((int, int, char *)); - -static void -nexti_command PARAMS ((char *, int)); - -static void -stepi_command PARAMS ((char *, int)); - -static void -next_command PARAMS ((char *, int)); - -static void -step_command PARAMS ((char *, int)); - -static void -run_command PARAMS ((char *, int)); - -#define ERROR_NO_INFERIOR \ - if (!target_has_execution) error ("The program is not being run."); - -/* String containing arguments to give to the program, separated by spaces. - Empty string (pointer to '\0') means no args. */ - -static char *inferior_args; - -/* File name for default use for standard in/out in the inferior. */ - -char *inferior_io_terminal; - -/* Pid of our debugged inferior, or 0 if no inferior now. - Since various parts of infrun.c test this to see whether there is a program - being debugged it should be nonzero (currently 3 is used) for remote - debugging. */ - -int inferior_pid; - -/* Last signal that the inferior received (why it stopped). */ - -enum target_signal stop_signal; - -/* Address at which inferior stopped. */ - -CORE_ADDR stop_pc; - -/* Stack frame when program stopped. */ - -FRAME_ADDR stop_frame_address; - -/* Chain containing status of breakpoint(s) that we have stopped at. */ - -bpstat stop_bpstat; - -/* Flag indicating that a command has proceeded the inferior past the - current breakpoint. */ - -int breakpoint_proceeded; - -/* Nonzero if stopped due to a step command. */ - -int stop_step; - -/* Nonzero if stopped due to completion of a stack dummy routine. */ - -int stop_stack_dummy; - -/* Nonzero if stopped due to a random (unexpected) signal in inferior - process. */ - -int stopped_by_random_signal; - -/* Range to single step within. - If this is nonzero, respond to a single-step signal - by continuing to step if the pc is in this range. */ - -CORE_ADDR step_range_start; /* Inclusive */ -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, - and how to set the frame for the breakpoint used to step out. */ - -FRAME_ADDR step_frame_address; - -/* 1 means step over all subroutine calls. - 0 means don't step over calls (used by stepi). - -1 means step over calls to undebuggable functions. */ - -int step_over_calls; - -/* If stepping, nonzero means step count is > 1 - so don't print frame next time inferior stops - if it stops due to stepping. */ - -int step_multi; - -/* Environment to use for running inferior, - in format described in environ.h. */ - -struct environ *inferior_environ; - - -/* ARGSUSED */ -void -tty_command (file, from_tty) - char *file; - int from_tty; -{ - if (file == 0) - error_no_arg ("terminal name for running target process"); - - inferior_io_terminal = savestring (file, strlen (file)); -} - -static void -run_command (args, from_tty) - char *args; - int from_tty; -{ - char *exec_file; - - dont_repeat (); - - /* Shouldn't this be target_has_execution? FIXME. */ - if (inferior_pid) - { - if ( - !query ("The program being debugged has been started already.\n\ -Start it from the beginning? ")) - error ("Program not restarted."); - target_kill (); - } - - clear_breakpoint_hit_counts (); - - exec_file = (char *) get_exec_file (0); - - /* 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 (); - - /* We keep symbols from add-symbol-file, on the grounds that the - user might want to add some symbols before running the program - (right?). But sometimes (dynamic loading where the user manually - introduces the new symbols with add-symbol-file), the code which - the symbols describe does not persist between runs. Currently - the user has to manually nuke all symbols between runs if they - want them to go away (PR 2207). This is probably reasonable. */ - - if (args) - { - char *cmd; - cmd = concat ("set args ", args, NULL); - make_cleanup (free, cmd); - execute_command (cmd, from_tty); - } - - if (from_tty) - { - puts_filtered("Starting program: "); - if (exec_file) - puts_filtered(exec_file); - puts_filtered(" "); - puts_filtered(inferior_args); - puts_filtered("\n"); - gdb_flush (gdb_stdout); - } - - target_create_inferior (exec_file, inferior_args, - environ_vector (inferior_environ)); -} - -static void -continue_command (proc_count_exp, from_tty) - char *proc_count_exp; - int from_tty; -{ - ERROR_NO_INFERIOR; - - /* If have argument, set proceed count of breakpoint we stopped at. */ - - if (proc_count_exp != NULL) - { - bpstat bs = stop_bpstat; - int num = bpstat_num (&bs); - if (num == 0 && from_tty) - { - printf_filtered - ("Not stopped at any breakpoint; argument ignored.\n"); - } - while (num != 0) - { - set_ignore_count (num, - parse_and_eval_address (proc_count_exp) - 1, - from_tty); - /* set_ignore_count prints a message ending with a period. - So print two spaces before "Continuing.". */ - if (from_tty) - printf_filtered (" "); - num = bpstat_num (&bs); - } - } - - if (from_tty) - printf_filtered ("Continuing.\n"); - - clear_proceed_status (); - - proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); -} - -/* Step until outside of current statement. */ - -/* ARGSUSED */ -static void -step_command (count_string, from_tty) - char *count_string; - int from_tty; -{ - step_1 (0, 0, count_string); -} - -/* Likewise, but skip over subroutine calls as if single instructions. */ - -/* ARGSUSED */ -static void -next_command (count_string, from_tty) - char *count_string; - int from_tty; -{ - step_1 (1, 0, count_string); -} - -/* Likewise, but step only one instruction. */ - -/* ARGSUSED */ -static void -stepi_command (count_string, from_tty) - char *count_string; - int from_tty; -{ - step_1 (0, 1, count_string); -} - -/* ARGSUSED */ -static void -nexti_command (count_string, from_tty) - char *count_string; - int from_tty; -{ - step_1 (1, 1, count_string); -} - -static void -step_1 (skip_subroutines, single_inst, count_string) - int skip_subroutines; - int single_inst; - char *count_string; -{ - register int count = 1; - FRAME fr; - struct cleanup *cleanups = 0; - - ERROR_NO_INFERIOR; - count = count_string ? parse_and_eval_address (count_string) : 1; - - if (!single_inst || skip_subroutines) /* leave si command alone */ - { - enable_longjmp_breakpoint(); - cleanups = make_cleanup(disable_longjmp_breakpoint, 0); - } - - for (; count > 0; count--) - { - clear_proceed_status (); - - fr = get_current_frame (); - if (!fr) /* Avoid coredump here. Why tho? */ - error ("No current frame"); - step_frame_address = FRAME_FP (fr); - - if (! single_inst) - { - find_pc_line_pc_range (stop_pc, &step_range_start, &step_range_end); - if (step_range_end == 0) - { - char *name; - if (find_pc_partial_function (stop_pc, &name, &step_range_start, - &step_range_end) == 0) - error ("Cannot find bounds of current function"); - - target_terminal_ours (); - printf_filtered ("\ -Single stepping until exit from function %s, \n\ -which has no line number information.\n", name); - gdb_flush (gdb_stdout); - } - } - else - { - /* Say we are stepping, but stop after one insn whatever it does. */ - step_range_start = step_range_end = 1; - if (!skip_subroutines) - /* It is stepi. - Don't step over function calls, not even to functions lacking - line numbers. */ - step_over_calls = 0; - } - - if (skip_subroutines) - step_over_calls = 1; - - step_multi = (count > 1); - proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); - if (! stop_step) - break; - - /* FIXME: On nexti, this may have already been done (when we hit the - step resume break, I think). Probably this should be moved to - wait_for_inferior (near the top). */ -#if defined (SHIFT_INST_REGS) - SHIFT_INST_REGS(); -#endif - } - - if (!single_inst || skip_subroutines) - do_cleanups(cleanups); -} - -/* Continue program at specified address. */ - -static void -jump_command (arg, from_tty) - char *arg; - int from_tty; -{ - register CORE_ADDR addr; - struct symtabs_and_lines sals; - struct symtab_and_line sal; - struct symbol *fn; - struct symbol *sfn; - - ERROR_NO_INFERIOR; - - if (!arg) - error_no_arg ("starting address"); - - sals = decode_line_spec_1 (arg, 1); - if (sals.nelts != 1) - { - error ("Unreasonable jump request"); - } - - sal = sals.sals[0]; - free ((PTR)sals.sals); - - if (sal.symtab == 0 && sal.pc == 0) - error ("No source file has been specified."); - - resolve_sal_pc (&sal); /* May error out */ - - /* See if we are trying to jump to another function. */ - fn = get_frame_function (get_current_frame ()); - sfn = find_pc_function (sal.pc); - if (fn != NULL && sfn != fn) - { - if (!query ("Line %d is not in `%s'. Jump anyway? ", sal.line, - SYMBOL_SOURCE_NAME (fn))) - { - error ("Not confirmed."); - /* NOTREACHED */ - } - } - - addr = sal.pc; - - if (from_tty) - { - printf_filtered ("Continuing at "); - print_address_numeric (addr, 1, gdb_stdout); - printf_filtered (".\n"); - } - - clear_proceed_status (); - proceed (addr, TARGET_SIGNAL_0, 0); -} - -/* Continue program giving it specified signal. */ - -static void -signal_command (signum_exp, from_tty) - char *signum_exp; - int from_tty; -{ - enum target_signal oursig; - - dont_repeat (); /* Too dangerous. */ - ERROR_NO_INFERIOR; - - if (!signum_exp) - error_no_arg ("signal number"); - - /* It would be even slicker to make signal names be valid expressions, - (the type could be "enum $signal" or some such), then the user could - assign them to convenience variables. */ - oursig = target_signal_from_name (signum_exp); - - if (oursig == TARGET_SIGNAL_UNKNOWN) - { - /* Not found as a name, try it as an expression. */ - /* 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. */ - int signum = parse_and_eval_address (signum_exp); - if (signum < 0 - || signum >= (int)TARGET_SIGNAL_LAST - || signum == (int)TARGET_SIGNAL_UNKNOWN - || signum == (int)TARGET_SIGNAL_DEFAULT) - error ("Invalid signal number %d.", signum); - oursig = signum; - } - - if (from_tty) - { - if (oursig == TARGET_SIGNAL_0) - printf_filtered ("Continuing with no signal.\n"); - else - printf_filtered ("Continuing with signal %s.\n", - target_signal_to_name (oursig)); - } - - clear_proceed_status (); - proceed (stop_pc, oursig, 0); -} - -/* Call breakpoint_auto_delete on the current contents of the bpstat - pointed to by arg (which is really a bpstat *). */ -void -breakpoint_auto_delete_contents (arg) - PTR arg; -{ - breakpoint_auto_delete (*(bpstat *)arg); -} - -/* Execute a "stack dummy", a piece of code stored in the stack - by the debugger to be executed in the inferior. - - To call: first, do PUSH_DUMMY_FRAME. - Then push the contents of the dummy. It should end with a breakpoint insn. - Then call here, passing address at which to start the dummy. - - The contents of all registers are saved before the dummy frame is popped - and copied into the buffer BUFFER. - - The dummy's frame is automatically popped whenever that break is hit. - If that is the first time the program stops, run_stack_dummy - returns to its caller with that frame already gone and returns 0. - Otherwise, run_stack-dummy returns 1 (the frame will eventually be popped - when we do hit that breakpoint). */ - -/* DEBUG HOOK: 4 => return instead of letting the stack dummy run. */ - -static int stack_dummy_testing = 0; - -int -run_stack_dummy (addr, buffer) - CORE_ADDR addr; - char buffer[REGISTER_BYTES]; -{ - struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0); - - /* Now proceed, having reached the desired place. */ - clear_proceed_status (); - if (stack_dummy_testing & 4) - { - POP_FRAME; - return(0); - } -#ifdef CALL_DUMMY_BREAKPOINT_OFFSET - { - struct breakpoint *bpt; - struct symtab_and_line sal; - -#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; - - /* Set up a FRAME for the dummy frame so we can pass it to - set_momentary_breakpoint. We need to give the breakpoint a - frame in case there is only one copy of the dummy (e.g. - CALL_DUMMY_LOCATION == AFTER_TEXT_END). */ - flush_cached_frames (); - set_current_frame (create_new_frame (read_fp (), sal.pc)); - - /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need to put - a breakpoint instruction. If not, the call dummy already has the - breakpoint instruction in it. - - addr is the address of the call dummy plus the CALL_DUMMY_START_OFFSET, - so we need to subtract the CALL_DUMMY_START_OFFSET. */ - bpt = set_momentary_breakpoint (sal, - get_current_frame (), - bp_call_dummy); - bpt->disposition = delete; - - /* If all error()s out of proceed ended up calling normal_stop (and - perhaps they should; it already does in the special case of error - out of resume()), then we wouldn't need this. */ - make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat); - } -#endif /* CALL_DUMMY_BREAKPOINT_OFFSET. */ - - proceed_to_finish = 1; /* We want stop_registers, please... */ - proceed (addr, TARGET_SIGNAL_0, 0); - - discard_cleanups (old_cleanups); - - if (!stop_stack_dummy) - return 1; - - /* On return, the stack dummy has been popped already. */ - - memcpy (buffer, stop_registers, sizeof stop_registers); - return 0; -} - -/* Proceed until we reach a different source line with pc greater than - our current one or exit the function. We skip calls in both cases. - - Note that eventually this command should probably be changed so - that only source lines are printed out when we hit the breakpoint - we set. This may involve changes to wait_for_inferior and the - proceed status code. */ - -/* ARGSUSED */ -static void -until_next_command (from_tty) - int from_tty; -{ - FRAME frame; - CORE_ADDR pc; - struct symbol *func; - struct symtab_and_line sal; - - clear_proceed_status (); - - frame = get_current_frame (); - - /* Step until either exited from this function or greater - than the current line (if in symbolic section) or pc (if - not). */ - - pc = read_pc (); - func = find_pc_function (pc); - - if (!func) - { - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc); - - if (msymbol == NULL) - error ("Execution is not within a known function."); - - step_range_start = SYMBOL_VALUE_ADDRESS (msymbol); - step_range_end = pc; - } - else - { - sal = find_pc_line (pc, 0); - - step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func)); - step_range_end = sal.end; - } - - step_over_calls = 1; - step_frame_address = FRAME_FP (frame); - - step_multi = 0; /* Only one call to proceed */ - - proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); -} - -static void -until_command (arg, from_tty) - char *arg; - int from_tty; -{ - if (!target_has_execution) - error ("The program is not running."); - if (arg) - until_break_command (arg, from_tty); - else - until_next_command (from_tty); -} - -/* "finish": Set a temporary breakpoint at the place - the selected frame will return to, then continue. */ - -static void -finish_command (arg, from_tty) - char *arg; - int from_tty; -{ - struct symtab_and_line sal; - register FRAME frame; - struct frame_info *fi; - register struct symbol *function; - struct breakpoint *breakpoint; - struct cleanup *old_chain; - - if (arg) - error ("The \"finish\" command does not take any arguments."); - if (!target_has_execution) - error ("The program is not running."); - if (selected_frame == NULL) - error ("No selected frame."); - - frame = get_prev_frame (selected_frame); - if (frame == 0) - error ("\"finish\" not meaningful in the outermost frame."); - - clear_proceed_status (); - - fi = get_frame_info (frame); - sal = find_pc_line (fi->pc, 0); - sal.pc = fi->pc; - - breakpoint = set_momentary_breakpoint (sal, frame, bp_finish); - - old_chain = make_cleanup(delete_breakpoint, breakpoint); - - /* Find the function we will return from. */ - - fi = get_frame_info (selected_frame); - function = find_pc_function (fi->pc); - - /* Print info on the selected frame, including level number - but not source. */ - if (from_tty) - { - printf_filtered ("Run till exit from "); - print_stack_frame (selected_frame, selected_frame_level, 0); - } - - proceed_to_finish = 1; /* We want stop_registers, please... */ - proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); - - /* Did we stop at our breakpoint? */ - if (bpstat_find_breakpoint(stop_bpstat, breakpoint) != NULL - && function != 0) - { - struct type *value_type; - register value_ptr val; - CORE_ADDR funcaddr; - - value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); - if (!value_type) - fatal ("internal: finish_command: function has no target type"); - - if (TYPE_CODE (value_type) == TYPE_CODE_VOID) - return; - - funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function)); - - val = value_being_returned (value_type, stop_registers, - using_struct_return (value_of_variable (function, NULL), - funcaddr, - 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"); - } - do_cleanups(old_chain); -} - -/* ARGSUSED */ -static void -program_info (args, from_tty) - char *args; - int from_tty; -{ - bpstat bs = stop_bpstat; - int num = bpstat_num (&bs); - - if (!target_has_execution) - { - printf_filtered ("The program being debugged is not being run.\n"); - return; - } - - target_files_info (); - printf_filtered ("Program stopped at %s.\n", - local_hex_string((unsigned long) stop_pc)); - if (stop_step) - printf_filtered ("It stopped after being stepped.\n"); - else if (num != 0) - { - /* There may be several breakpoints in the same place, so this - isn't as strange as it seems. */ - while (num != 0) - { - if (num < 0) - printf_filtered ("It stopped at a breakpoint that has since been deleted.\n"); - else - printf_filtered ("It stopped at breakpoint %d.\n", num); - num = bpstat_num (&bs); - } - } - else if (stop_signal != TARGET_SIGNAL_0) - { - printf_filtered ("It stopped with signal %s, %s.\n", - target_signal_to_name (stop_signal), - target_signal_to_string (stop_signal)); - } - - if (!from_tty) - printf_filtered ("Type \"info stack\" or \"info registers\" for more information.\n"); -} - -static void -environment_info (var, from_tty) - char *var; - int from_tty; -{ - if (var) - { - register char *val = get_in_environ (inferior_environ, var); - if (val) - { - puts_filtered (var); - puts_filtered (" = "); - puts_filtered (val); - puts_filtered ("\n"); - } - else - { - puts_filtered ("Environment variable \""); - puts_filtered (var); - puts_filtered ("\" not defined.\n"); - } - } - else - { - register char **vector = environ_vector (inferior_environ); - while (*vector) - { - puts_filtered (*vector++); - puts_filtered ("\n"); - } - } -} - -static void -set_environment_command (arg, from_tty) - char *arg; - int from_tty; -{ - register char *p, *val, *var; - int nullset = 0; - - if (arg == 0) - error_no_arg ("environment variable and value"); - - /* Find seperation between variable name and value */ - p = (char *) strchr (arg, '='); - val = (char *) strchr (arg, ' '); - - if (p != 0 && val != 0) - { - /* We have both a space and an equals. If the space is before the - equals, walk forward over the spaces til we see a nonspace - (possibly the equals). */ - if (p > val) - while (*val == ' ') - val++; - - /* Now if the = is after the char following the spaces, - take the char following the spaces. */ - if (p > val) - p = val - 1; - } - else if (val != 0 && p == 0) - p = val; - - if (p == arg) - error_no_arg ("environment variable to set"); - - if (p == 0 || p[1] == 0) - { - nullset = 1; - if (p == 0) - p = arg + strlen (arg); /* So that savestring below will work */ - } - else - { - /* Not setting variable value to null */ - val = p + 1; - while (*val == ' ' || *val == '\t') - val++; - } - - while (p != arg && (p[-1] == ' ' || p[-1] == '\t')) p--; - - var = savestring (arg, p - arg); - if (nullset) - { - printf_filtered ("Setting environment variable \"%s\" to null value.\n", var); - set_in_environ (inferior_environ, var, ""); - } - else - set_in_environ (inferior_environ, var, val); - free (var); -} - -static void -unset_environment_command (var, from_tty) - char *var; - int from_tty; -{ - if (var == 0) - { - /* If there is no argument, delete all environment variables. - Ask for confirmation if reading from the terminal. */ - if (!from_tty || query ("Delete all environment variables? ")) - { - free_environ (inferior_environ); - inferior_environ = make_environ (); - } - } - else - unset_in_environ (inferior_environ, var); -} - -/* Handle the execution path (PATH variable) */ - -static const char path_var_name[] = "PATH"; - -/* ARGSUSED */ -static void -path_info (args, from_tty) - char *args; - int from_tty; -{ - puts_filtered ("Executable and object file path: "); - puts_filtered (get_in_environ (inferior_environ, path_var_name)); - puts_filtered ("\n"); -} - -/* Add zero or more directories to the front of the execution path. */ - -static void -path_command (dirname, from_tty) - char *dirname; - int from_tty; -{ - char *exec_path; - - dont_repeat (); - exec_path = strsave (get_in_environ (inferior_environ, path_var_name)); - mod_path (dirname, &exec_path); - set_in_environ (inferior_environ, path_var_name, exec_path); - free (exec_path); - if (from_tty) - path_info ((char *)NULL, from_tty); -} - -const char * const reg_names[] = REGISTER_NAMES; - -/* Print out the machine register regnum. If regnum is -1, - print all registers (fpregs == 1) or all non-float registers - (fpregs == 0). - - For most machines, having all_registers_info() print the - register(s) one per line is good enough. If a different format - is required, (eg, for MIPS or Pyramid 90x, which both have - lots of regs), or there is an existing convention for showing - all the registers, define the macro DO_REGISTERS_INFO(regnum, fp) - to provide that format. */ - -#if !defined (DO_REGISTERS_INFO) - -#define DO_REGISTERS_INFO(regnum, fp) do_registers_info(regnum, fp) - -static void -do_registers_info (regnum, fpregs) - int regnum; - int fpregs; -{ - register int i; - int numregs = ARCH_NUM_REGS; - - for (i = 0; i < numregs; i++) - { - char raw_buffer[MAX_REGISTER_RAW_SIZE]; - char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; - - /* Decide between printing all regs, nonfloat regs, or specific reg. */ - if (regnum == -1) { - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT && !fpregs) - continue; - } else { - if (i != regnum) - continue; - } - - fputs_filtered (reg_names[i], gdb_stdout); - print_spaces_filtered (15 - strlen (reg_names[i]), gdb_stdout); - - /* Get the data in raw format. */ - if (read_relative_register_raw_bytes (i, raw_buffer)) - { - printf_filtered ("Invalid register contents\n"); - continue; - } - - /* Convert raw data to virtual format if necessary. */ -#ifdef REGISTER_CONVERTIBLE - if (REGISTER_CONVERTIBLE (i)) - { - REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i), - raw_buffer, virtual_buffer); - } - else -#endif - memcpy (virtual_buffer, raw_buffer, - REGISTER_VIRTUAL_SIZE (i)); - - /* If virtual format is floating, print it that way, and in raw hex. */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT - && ! INVALID_FLOAT (virtual_buffer, REGISTER_VIRTUAL_SIZE (i))) - { - register int j; - - val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 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]); - printf_filtered (")"); - } - -/* FIXME! val_print probably can handle all of these cases now... */ - - /* Else if virtual format is too long for printf, - print in hex a byte at a time. */ - else if (REGISTER_VIRTUAL_SIZE (i) > sizeof (long)) - { - register int j; - printf_filtered ("0x"); - for (j = 0; j < REGISTER_VIRTUAL_SIZE (i); j++) - printf_filtered ("%02x", (unsigned char)virtual_buffer[j]); - } - /* Else print as integer in hex and in decimal. */ - else - { - val_print (REGISTER_VIRTUAL_TYPE (i), raw_buffer, 0, - gdb_stdout, 'x', 1, 0, Val_pretty_default); - printf_filtered ("\t"); - val_print (REGISTER_VIRTUAL_TYPE (i), raw_buffer, 0, - gdb_stdout, 0, 1, 0, Val_pretty_default); - } - - /* The SPARC wants to print even-numbered float regs as doubles - in addition to printing them as floats. */ -#ifdef PRINT_REGISTER_HOOK - PRINT_REGISTER_HOOK (i); -#endif - - printf_filtered ("\n"); - } -} -#endif /* no DO_REGISTERS_INFO. */ - -static void -registers_info (addr_exp, fpregs) - char *addr_exp; - int fpregs; -{ - int regnum, numregs; - register char *end; - - if (!target_has_registers) - error ("The program has no registers now."); - - if (!addr_exp) - { - DO_REGISTERS_INFO(-1, fpregs); - return; - } - - do - { - if (addr_exp[0] == '$') - addr_exp++; - end = addr_exp; - 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; - if (*addr_exp >= '0' && *addr_exp <= '9') - regnum = atoi (addr_exp); /* Take a number */ - if (regnum >= numregs) /* Bad name, or bad number */ - error ("%.*s: invalid register", end - addr_exp, addr_exp); - -found: - DO_REGISTERS_INFO(regnum, fpregs); - - addr_exp = end; - while (*addr_exp == ' ' || *addr_exp == '\t') - ++addr_exp; - } while (*addr_exp != '\0'); -} - -static void -all_registers_info (addr_exp, from_tty) - char *addr_exp; - int from_tty; -{ - registers_info (addr_exp, 1); -} - -static void -nofp_registers_info (addr_exp, from_tty) - char *addr_exp; - int from_tty; -{ - registers_info (addr_exp, 0); -} - -/* - * TODO: - * Should save/restore the tty state since it might be that the - * program to be debugged was started on this tty and it wants - * the tty in some state other than what we want. If it's running - * on another terminal or without a terminal, then saving and - * restoring the tty state is a harmless no-op. - * This only needs to be done if we are attaching to a process. - */ - -/* - attach_command -- - takes a program started up outside of gdb and ``attaches'' to it. - This stops it cold in its tracks and allows us to start debugging it. - and wait for the trace-trap that results from attaching. */ - -void -attach_command (args, from_tty) - char *args; - int from_tty; -{ - dont_repeat (); /* Not for the faint of heart */ - - if (target_has_execution) - { - if (query ("A program is being debugged already. Kill it? ")) - target_kill (); - else - error ("Not killed."); - } - - target_attach (args, from_tty); - - /* 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 (); - - /* Set up execution context to know that we should return from - wait_for_inferior as soon as the target reports a stop. */ - init_wait_for_inferior (); - clear_proceed_status (); - stop_soon_quietly = 1; - -#ifndef MACH - /* Mach 3 does not generate any traps when attaching to inferior, - and to set up frames we can do this. */ - - wait_for_inferior (); -#endif - -#ifdef SOLIB_ADD - /* Add shared library symbols from the newly attached process, if any. */ - SOLIB_ADD ((char *)0, from_tty, (struct target_ops *)0); -#endif - - normal_stop (); -} - -/* - * detach_command -- - * takes a program previously attached to and detaches it. - * The program resumes execution and will no longer stop - * on signals, etc. We 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 -detach_command (args, from_tty) - char *args; - int from_tty; -{ - dont_repeat (); /* Not for the faint of heart */ - if (remove_breakpoints ()) - printf("detach_command: couldn't remove all breakpoints!\n"); - target_detach (args, from_tty); -} - -/* ARGSUSED */ -static void -float_info (addr_exp, from_tty) - char *addr_exp; - int from_tty; -{ -#ifdef FLOAT_INFO - FLOAT_INFO; -#else - printf_filtered ("No floating point info available for this processor.\n"); -#endif -} - -/* ARGSUSED */ -static void -unset_command (args, from_tty) - char *args; - int from_tty; -{ - printf_filtered ("\"unset\" must be followed by the name of an unset subcommand.\n"); - help_list (unsetlist, "unset ", -1, gdb_stdout); -} - -void -_initialize_infcmd () -{ - struct cmd_list_element *c; - - add_com ("tty", class_run, tty_command, - "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\ -Follow this command with any number of args, to be passed to the program.", - &setlist), - &showlist); - - c = add_cmd - ("environment", no_class, environment_info, - "The environment to give the program, or one variable's value.\n\ -With an argument VAR, prints the value of environment variable VAR to\n\ -give the program being debugged. With no arguments, prints the entire\n\ -environment to be given to the program.", &showlist); - c->completer = noop_completer; - - add_prefix_cmd ("unset", no_class, unset_command, - "Complement to certain \"set\" commands", - &unsetlist, "unset ", 0, &cmdlist); - - c = add_cmd ("environment", class_run, unset_environment_command, - "Cancel environment variable VAR for the program.\n\ -This does not affect the program until the next \"run\" command.", - &unsetlist); - c->completer = noop_completer; - - c = add_cmd ("environment", class_run, set_environment_command, - "Set environment variable value to give the program.\n\ -Arguments are VAR VALUE where VAR is variable name and VALUE is value.\n\ -VALUES of environment variables are uninterpreted strings.\n\ -This does not affect the program until the next \"run\" command.", - &setlist); - c->completer = noop_completer; - - add_com ("path", class_files, path_command, - "Add directory DIR(s) to beginning of search path for object files.\n\ -$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."); - - c = add_cmd ("paths", no_class, path_info, - "Current search path for finding object files.\n\ -$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); - 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\ -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."); - - 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."); - - add_com ("signal", class_run, signal_command, - "Continue program giving it signal number SIGNUMBER."); - - add_com ("stepi", class_run, stepi_command, - "Step one instruction exactly.\n\ -Argument N means do this N times (or till program stops for another reason)."); - add_com_alias ("si", "stepi", class_alias, 0); - - add_com ("nexti", class_run, nexti_command, - "Step one instruction, but proceed through subroutine calls.\n\ -Argument N means do this N times (or till program stops for another reason)."); - add_com_alias ("ni", "nexti", class_alias, 0); - - add_com ("finish", class_run, finish_command, - "Execute until selected stack frame returns.\n\ -Upon return, the value returned is printed and put in the value history."); - - add_com ("next", class_run, next_command, - "Step program, proceeding through subroutine calls.\n\ -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); - - add_com ("step", class_run, step_command, - "Step program until it reaches a different source line.\n\ -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\ -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); - - add_com ("jump", class_run, jump_command, - "Continue program being debugged at specified line or address.\n\ -Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\ -for an address to start at."); - - 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\ -which means to set the ignore count of that breakpoint to N - 1 (so that\n\ -the breakpoint won't break until the Nth time it is reached)."); - add_com_alias ("c", "cont", class_run, 1); - add_com_alias ("fg", "cont", class_run, 1); - - add_com ("run", class_run, run_command, - "Start debugged program. You may specify arguments to give it.\n\ -Args may include \"*\", or \"[...]\"; they are expanded using \"sh\".\n\ -Input and output redirection with \">\", \"<\", or \">>\" are also allowed.\n\n\ -With no arguments, uses arguments last specified (with \"run\" or \"set args\").\n\ -To cancel previous arguments and run with no arguments,\n\ -use \"set args\" without arguments."); - add_com_alias ("r", "run", class_run, 1); - - 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."); - - add_info ("all-registers", all_registers_info, -"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, - "Execution status of the program."); - - add_info ("float", float_info, - "Print the status of the floating point unit\n"); - - inferior_args = savestring ("", 1); /* Initially no args */ - inferior_environ = make_environ (); - init_environ (inferior_environ); -} diff --git a/gnu/usr.bin/gdb/gdb/inferior.h b/gnu/usr.bin/gdb/gdb/inferior.h deleted file mode 100644 index 6fd94a6..0000000 --- a/gnu/usr.bin/gdb/gdb/inferior.h +++ /dev/null @@ -1,420 +0,0 @@ -/* 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. - -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 (INFERIOR_H) -#define INFERIOR_H 1 - -/* For bpstat. */ -#include "breakpoint.h" - -/* For FRAME_ADDR. */ -#include "frame.h" - -/* For enum target_signal. */ -#include "target.h" - -/* - * Structure in which to save the status of the inferior. Save - * through "save_inferior_status", restore through - * "restore_inferior_status". - * This pair of routines should be called around any transfer of - * 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; - FRAME_ADDR stop_frame_address; - 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; - FRAME_ADDR step_frame_address; - int step_over_calls; - CORE_ADDR step_resume_break_address; - int stop_after_trap; - int stop_soon_quietly; - FRAME_ADDR selected_frame_address; - int selected_level; - 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]; - - 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, - perhaps depending on the actual CPU in use or program being run. */ - -#ifndef ARCH_NUM_REGS -#define ARCH_NUM_REGS NUM_REGS -#endif - -extern void -save_inferior_status PARAMS ((struct inferior_status *, int)); - -extern void -restore_inferior_status PARAMS ((struct inferior_status *)); - -extern void set_sigint_trap PARAMS ((void)); -extern void clear_sigint_trap PARAMS ((void)); - -extern void set_sigio_trap PARAMS ((void)); -extern void clear_sigio_trap PARAMS ((void)); - -/* File name for default use for standard in/out in the inferior. */ - -extern char *inferior_io_terminal; - -/* Pid of our debugged inferior, or 0 if no inferior now. */ - -extern int inferior_pid; - -/* Character array containing an image of the inferior programs' registers. */ - -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. */ - -extern char register_valid[NUM_REGS]; - -extern void -clear_proceed_status PARAMS ((void)); - -extern void -proceed PARAMS ((CORE_ADDR, enum target_signal, int)); - -extern void -kill_inferior PARAMS ((void)); - -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 CORE_ADDR -read_pc PARAMS ((void)); - -extern CORE_ADDR -read_pc_pid PARAMS ((int)); - -extern void -write_pc PARAMS ((CORE_ADDR)); - -extern CORE_ADDR -read_sp PARAMS ((void)); - -extern void -write_sp PARAMS ((CORE_ADDR)); - -extern CORE_ADDR -read_fp PARAMS ((void)); - -extern void -write_fp PARAMS ((CORE_ADDR)); - -extern void -wait_for_inferior PARAMS ((void)); - -extern void -init_wait_for_inferior PARAMS ((void)); - -extern void -close_exec_file PARAMS ((void)); - -extern void -reopen_exec_file PARAMS ((void)); - -/* The `resume' routine should only be called in special circumstances. - Normally, use `proceed', which handles a lot of bookkeeping. */ -extern void -resume PARAMS ((int, enum target_signal)); - -/* From misc files */ - -extern void -store_inferior_registers PARAMS ((int)); - -extern void -fetch_inferior_registers PARAMS ((int)); - -extern void -solib_create_inferior_hook PARAMS ((void)); - -extern void -child_terminal_info PARAMS ((char *, int)); - -extern void -term_info PARAMS ((char *, int)); - -extern void -terminal_ours_for_output PARAMS ((void)); - -extern void -terminal_inferior PARAMS ((void)); - -extern void -terminal_init_inferior PARAMS ((void)); - -/* From infptrace.c */ - -extern int -attach PARAMS ((int)); - -void -detach PARAMS ((int)); - -extern void -child_resume PARAMS ((int, int, enum target_signal)); - -#ifndef PTRACE_ARG3_TYPE -#define PTRACE_ARG3_TYPE int /* Correct definition for most systems. */ -#endif - -extern int -call_ptrace PARAMS ((int, int, PTRACE_ARG3_TYPE, int)); - -/* From procfs.c */ - -extern int -proc_iterate_over_mappings PARAMS ((int (*) (int, CORE_ADDR))); - -/* From fork-child.c */ - -extern void fork_inferior PARAMS ((char *, char *, char **, - void (*) (void), - void (*) (int), char *)); - -extern void startup_inferior PARAMS ((int)); - -/* From inflow.c */ - -extern void -new_tty_prefork PARAMS ((char *)); - -extern int gdb_has_a_terminal PARAMS ((void)); - -/* From infrun.c */ - -extern void -start_remote PARAMS ((void)); - -extern void -normal_stop PARAMS ((void)); - -extern int -signal_stop_state PARAMS ((int)); - -extern int -signal_print_state PARAMS ((int)); - -extern int -signal_pass_state PARAMS ((int)); - -/* From infcmd.c */ - -extern void -tty_command PARAMS ((char *, int)); - -extern void -attach_command PARAMS ((char *, int)); - -/* Last signal that the inferior received (why it stopped). */ - -extern enum target_signal stop_signal; - -/* Address at which inferior stopped. */ - -extern CORE_ADDR stop_pc; - -/* Stack frame when program stopped. */ - -extern FRAME_ADDR stop_frame_address; - -/* Chain containing status of breakpoint(s) that we have stopped at. */ - -extern bpstat stop_bpstat; - -/* Flag indicating that a command has proceeded the inferior past the - current breakpoint. */ - -extern int breakpoint_proceeded; - -/* Nonzero if stopped due to a step command. */ - -extern int stop_step; - -/* Nonzero if stopped due to completion of a stack dummy routine. */ - -extern int stop_stack_dummy; - -/* Nonzero if program stopped due to a random (unexpected) signal in - inferior process. */ - -extern int stopped_by_random_signal; - -/* Range to single step within. - If this is nonzero, respond to a single-step signal - by continuing to step if the pc is in this range. - - If step_range_start and step_range_end are both 1, it means to step for - a single instruction (FIXME: it might clean up wait_for_inferior in a - 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 */ - -/* Stack frame address as of when stepping command was issued. - This is how we know when we step into a subroutine call, - and how to set the frame for the breakpoint used to step out. */ - -extern FRAME_ADDR step_frame_address; - -/* 1 means step over all subroutine calls. - -1 means step over calls to undebuggable functions. */ - -extern int step_over_calls; - -/* If stepping, nonzero means step count is > 1 - so don't print frame next time inferior stops - if it stops due to stepping. */ - -extern int step_multi; - -/* Nonzero means expecting a trap and caller will handle it themselves. - It is used after attach, due to attaching to a process; - when running in the shell before the child program has been exec'd; - and when running some kinds of remote stuff (FIXME?). */ - -extern int stop_soon_quietly; - -/* Nonzero if proceed is being used for a "finish" command or a similar - situation when stop_registers should be saved. */ - -extern int proceed_to_finish; - -/* Save register contents here when about to pop a stack dummy frame, - if-and-only-if proceed_to_finish is set. - Thus this contains the return value from the called function (assuming - values are returned in a register). */ - -extern char stop_registers[REGISTER_BYTES]; - -/* Nonzero if the child process in inferior_pid was attached rather - than forked. */ - -extern int attach_flag; - -/* Sigtramp is a routine that the kernel calls (which then calls the - signal handler). On most machines it is a library routine that - is linked into the executable. - - This macro, given a program counter value and the name of the - function in which that PC resides (which can be null if the - name is not known), returns nonzero if the PC and name show - that we are in sigtramp. - - 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 \ - ) -# else -# define IN_SIGTRAMP(pc, name) \ - (name && STREQ ("_sigtramp", name)) -# endif -#endif - -/* Possible values for CALL_DUMMY_LOCATION. */ -#define ON_STACK 1 -#define BEFORE_TEXT_END 2 -#define AFTER_TEXT_END 3 -#define AT_ENTRY_POINT 4 - -#if !defined (CALL_DUMMY_LOCATION) -#define CALL_DUMMY_LOCATION ON_STACK -#endif /* No CALL_DUMMY_LOCATION. */ - -/* Are we in a call dummy? The code below which allows DECR_PC_AFTER_BREAK - below is for infrun.c, which may give the macro a pc without that - subtracted out. */ -#if !defined (PC_IN_CALL_DUMMY) -#if CALL_DUMMY_LOCATION == BEFORE_TEXT_END -extern CORE_ADDR text_end; -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) \ - ((pc) >= text_end - CALL_DUMMY_LENGTH \ - && (pc) <= text_end + DECR_PC_AFTER_BREAK) -#endif /* Before text_end. */ - -#if CALL_DUMMY_LOCATION == AFTER_TEXT_END -extern CORE_ADDR text_end; -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) \ - ((pc) >= text_end \ - && (pc) <= text_end + CALL_DUMMY_LENGTH + DECR_PC_AFTER_BREAK) -#endif /* After text_end. */ - -#if CALL_DUMMY_LOCATION == ON_STACK -/* Is the PC in a call dummy? SP and FRAME_ADDRESS are the bottom and - top of the stack frame which we are checking, where "bottom" and - "top" refer to some section of memory which contains the code for - the call dummy. Calls to this macro assume that the contents of - SP_REGNUM and FP_REGNUM (or the saved values thereof), respectively, - are the things to pass. - - This won't work on the 29k, where SP_REGNUM and FP_REGNUM don't - have that meaning, but the 29k doesn't use ON_STACK. This could be - fixed by generalizing this scheme, perhaps by passing in a frame - and adding a few fields, at least on machines which need them for - PC_IN_CALL_DUMMY. - - Something simpler, like checking for the stack segment, doesn't work, - since various programs (threads implementations, gcc nested function - stubs, etc) may either allocate stack frames in another segment, or - 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)) -#endif /* On stack. */ - -#if CALL_DUMMY_LOCATION == AT_ENTRY_POINT -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) \ - ((pc) >= CALL_DUMMY_ADDRESS () \ - && (pc) <= (CALL_DUMMY_ADDRESS () + DECR_PC_AFTER_BREAK)) -#endif /* At entry point. */ -#endif /* No PC_IN_CALL_DUMMY. */ - -#endif /* !defined (INFERIOR_H) */ diff --git a/gnu/usr.bin/gdb/gdb/inflow.c b/gnu/usr.bin/gdb/gdb/inflow.c deleted file mode 100644 index fc937da..0000000 --- a/gnu/usr.bin/gdb/gdb/inflow.c +++ /dev/null @@ -1,711 +0,0 @@ -/* Low level interface to ptrace, for GDB when running under Unix. - Copyright 1986, 1987, 1989, 1991, 1992 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 "defs.h" -#include "frame.h" -#include "inferior.h" -#include "command.h" -#include "signals.h" -#include "serial.h" -#include "terminal.h" -#include "target.h" -#include "thread.h" - -#include -#include - -#if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY) && !defined (__GO32__) -#define HAVE_SGTTY -#endif - -#if defined (HAVE_TERMIOS) -#include -#include -#endif - -#ifdef HAVE_TERMIOS -#define PROCESS_GROUP_TYPE pid_t -#endif - -#ifdef HAVE_SGTTY -#ifdef SHORT_PGRP -/* This is only used for the ultra. Does it have pid_t? */ -#define PROCESS_GROUP_TYPE short -#else -#define PROCESS_GROUP_TYPE int -#endif -#endif /* sgtty */ - -static void -kill_command PARAMS ((char *, int)); - -static void -terminal_ours_1 PARAMS ((int)); - -/* Record terminal status separately for debugger and inferior. */ - -static serial_t stdin_serial; - -/* TTY state for the inferior. We save it whenever the inferior stops, and - restore it when it resumes. */ -static serial_ttystate inferior_ttystate; - -/* Our own tty state, which we restore every time we need to deal with the - terminal. We only set it once, when GDB first starts. The settings of - flags which readline saves and restores and unimportant. */ -static serial_ttystate our_ttystate; - -/* fcntl flags for us and the inferior. Saved and restored just like - {our,inferior}_ttystate. */ -static int tflags_inferior; -static int tflags_ours; - -#ifdef PROCESS_GROUP_TYPE -/* Process group for us and the inferior. Saved and restored just like - {our,inferior}_ttystate. */ -PROCESS_GROUP_TYPE our_process_group; -PROCESS_GROUP_TYPE inferior_process_group; -#endif - -/* While the inferior is running, we want SIGINT and SIGQUIT to go to the - 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) (); - -/* The name of the tty (from the `tty' command) that we gave to the inferior - when it was last started. */ - -static char *inferior_thisrun_terminal; - -/* Nonzero if our terminal settings are in effect. Zero if the - inferior's settings are in effect. Ignored if !gdb_has_a_terminal - (). */ - -static int terminal_is_ours; - -enum {yes, no, have_not_checked} gdb_has_a_terminal_flag = have_not_checked; - -/* Does GDB have a terminal (on stdin)? */ -int -gdb_has_a_terminal () -{ - switch (gdb_has_a_terminal_flag) - { - case yes: - return 1; - case no: - return 0; - case have_not_checked: - /* Get all the current tty settings (including whether we have a tty at - all!). Can't do this in _initialize_inflow because SERIAL_FDOPEN - won't work until the serial_ops_list is initialized. */ - -#ifdef F_GETFL - tflags_ours = fcntl (0, F_GETFL, 0); -#endif - - gdb_has_a_terminal_flag = no; - stdin_serial = SERIAL_FDOPEN (0); - if (stdin_serial != NULL) - { - our_ttystate = SERIAL_GET_TTY_STATE (stdin_serial); - - if (our_ttystate != NULL) - { - gdb_has_a_terminal_flag = yes; -#ifdef HAVE_TERMIOS - our_process_group = tcgetpgrp (0); -#endif -#ifdef HAVE_SGTTY - ioctl (0, TIOCGPGRP, &our_process_group); -#endif - } - } - - return gdb_has_a_terminal_flag == yes; - default: - /* "Can't happen". */ - return 0; - } -} - -/* Macro for printing errors from ioctl operations */ - -#define OOPSY(what) \ - if (result == -1) \ - fprintf_unfiltered(gdb_stderr, "[%s failed in terminal_inferior: %s]\n", \ - what, strerror (errno)) - -static void terminal_ours_1 PARAMS ((int)); - -/* Initialize the terminal settings we record for the inferior, - before we actually run the inferior. */ - -void -terminal_init_inferior () -{ - if (gdb_has_a_terminal ()) - { - /* We could just as well copy our_ttystate (if we felt like adding - a new function SERIAL_COPY_TTY_STATE). */ - 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 -#endif - - /* Make sure that next time we call terminal_inferior (which will be - before the program runs, as it needs to be), we install the new - process group. */ - terminal_is_ours = 1; - } -} - -/* Put the inferior's terminal settings into effect. - This is preparation for starting or resuming the inferior. */ - -void -terminal_inferior () -{ - if (gdb_has_a_terminal () && terminal_is_ours - && inferior_thisrun_terminal == 0) - { - int result; - -#ifdef F_GETFL - /* Is there a reason this is being done twice? It happens both - places we use F_SETFL, so I'm inclined to think perhaps there - is some reason, however perverse. Perhaps not though... */ - result = fcntl (0, F_SETFL, tflags_inferior); - result = fcntl (0, F_SETFL, tflags_inferior); - OOPSY ("fcntl F_SETFL"); -#endif - - /* Because we were careful to not change in or out of raw mode in - terminal_ours, we will not change in our out of raw mode with - this call, so we don't flush any input. */ - result = SERIAL_SET_TTY_STATE (stdin_serial, inferior_ttystate); - OOPSY ("setting tty state"); - - if (!job_control) - { - sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN); - sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN); - } - - /* If attach_flag is set, we don't know whether we are sharing a - terminal with the inferior or not. (attaching a process - without a terminal is one case where we do not; attaching a - process which we ran from the same shell as GDB via `&' is - one case where we do, I think (but perhaps this is not - `sharing' in the sense that we need to save and restore tty - state)). I don't know if there is any way to tell whether we - are sharing a terminal. So what we do is to go through all - the saving and restoring of the tty state, but ignore errors - setting the process group, which will happen if we are not - sharing a terminal). */ - - if (job_control) - { -#ifdef HAVE_TERMIOS - result = tcsetpgrp (0, inferior_process_group); - if (!attach_flag) - OOPSY ("tcsetpgrp"); -#endif - -#ifdef HAVE_SGTTY - result = ioctl (0, TIOCSPGRP, &inferior_process_group); - if (!attach_flag) - OOPSY ("TIOCSPGRP"); -#endif - } - - } - terminal_is_ours = 0; -} - -/* Put some of our terminal settings into effect, - enough to get proper results from our output, - but do not change into or out of RAW mode - so that no input is discarded. - - After doing this, either terminal_ours or terminal_inferior - should be called to get back to a normal state of affairs. */ - -void -terminal_ours_for_output () -{ - terminal_ours_1 (1); -} - -/* Put our terminal settings into effect. - First record the inferior's terminal settings - so they can be restored properly later. */ - -void -terminal_ours () -{ - terminal_ours_1 (0); -} - -/* output_only is not used, and should not be used unless we introduce - separate terminal_is_ours and terminal_is_ours_for_output - flags. */ - -static void -terminal_ours_1 (output_only) - int output_only; -{ - /* Checking inferior_thisrun_terminal is necessary so that - if GDB is running in the background, it won't block trying - to do the ioctl()'s below. Checking gdb_has_a_terminal - avoids attempting all the ioctl's when running in batch. */ - if (inferior_thisrun_terminal != 0 || gdb_has_a_terminal () == 0) - return; - - if (!terminal_is_ours) - { - /* Ignore this signal since it will happen when we try to set the - pgrp. */ - void (*osigttou) (); - int result; - - terminal_is_ours = 1; - -#ifdef SIGTTOU - if (job_control) - osigttou = (void (*) ()) signal (SIGTTOU, SIG_IGN); -#endif - - if (inferior_ttystate) - free (inferior_ttystate); - inferior_ttystate = SERIAL_GET_TTY_STATE (stdin_serial); -#ifdef HAVE_TERMIOS - inferior_process_group = tcgetpgrp (0); -#endif -#ifdef HAVE_SGTTY - ioctl (0, TIOCGPGRP, &inferior_process_group); -#endif - - /* Here we used to set ICANON in our ttystate, but I believe this - was an artifact from before when we used readline. Readline sets - the tty state when it needs to. - FIXME-maybe: However, query() expects non-raw mode and doesn't - use readline. Maybe query should use readline (on the other hand, - this only matters for HAVE_SGTTY, not termio or termios, I think). */ - - /* Set tty state to our_ttystate. We don't change in our out of raw - mode, to avoid flushing input. We need to do the same thing - regardless of output_only, because we don't have separate - terminal_is_ours and terminal_is_ours_for_output flags. It's OK, - though, since readline will deal with raw mode when/if it needs to. - */ - - SERIAL_NOFLUSH_SET_TTY_STATE (stdin_serial, our_ttystate, - inferior_ttystate); - - if (job_control) - { -#ifdef HAVE_TERMIOS - result = tcsetpgrp (0, our_process_group); -#if 0 - /* This fails on Ultrix with EINVAL if you run the testsuite - in the background with nohup, and then log out. GDB never - used to check for an error here, so perhaps there are other - such situations as well. */ - if (result == -1) - fprintf_unfiltered (gdb_stderr, "[tcsetpgrp failed in terminal_ours: %s]\n", - strerror (errno)); -#endif -#endif /* termios */ - -#ifdef HAVE_SGTTY - result = ioctl (0, TIOCSPGRP, &our_process_group); -#endif - } - -#ifdef SIGTTOU - if (job_control) - signal (SIGTTOU, osigttou); -#endif - - if (!job_control) - { - signal (SIGINT, sigint_ours); - signal (SIGQUIT, sigquit_ours); - } - -#ifdef F_GETFL - tflags_inferior = fcntl (0, F_GETFL, 0); - - /* Is there a reason this is being done twice? It happens both - places we use F_SETFL, so I'm inclined to think perhaps there - is some reason, however perverse. Perhaps not though... */ - result = fcntl (0, F_SETFL, tflags_ours); - result = fcntl (0, F_SETFL, tflags_ours); -#endif - - result = result; /* lint */ - } -} - -/* ARGSUSED */ -void -term_info (arg, from_tty) - char *arg; - int from_tty; -{ - target_terminal_info (arg, from_tty); -} - -/* ARGSUSED */ -void -child_terminal_info (args, from_tty) - char *args; - int from_tty; -{ - if (!gdb_has_a_terminal ()) - { - printf_filtered ("This GDB does not control a terminal.\n"); - return; - } - - printf_filtered ("Inferior's terminal status (currently saved by GDB):\n"); - - /* First the fcntl flags. */ - { - int flags; - - flags = tflags_inferior; - - printf_filtered ("File descriptor flags = "); - -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) -#endif - /* (O_ACCMODE) parens are to avoid Ultrix header file bug */ - switch (flags & (O_ACCMODE)) - { - case O_RDONLY: printf_filtered ("O_RDONLY"); break; - case O_WRONLY: printf_filtered ("O_WRONLY"); break; - case O_RDWR: printf_filtered ("O_RDWR"); break; - } - flags &= ~(O_ACCMODE); - -#ifdef O_NONBLOCK - if (flags & O_NONBLOCK) - printf_filtered (" | O_NONBLOCK"); - flags &= ~O_NONBLOCK; -#endif - -#if defined (O_NDELAY) - /* If O_NDELAY and O_NONBLOCK are defined to the same thing, we will - print it as O_NONBLOCK, which is good cause that is what POSIX - has, and the flag will already be cleared by the time we get here. */ - if (flags & O_NDELAY) - printf_filtered (" | O_NDELAY"); - flags &= ~O_NDELAY; -#endif - - if (flags & O_APPEND) - printf_filtered (" | O_APPEND"); - flags &= ~O_APPEND; - -#if defined (O_BINARY) - if (flags & O_BINARY) - printf_filtered (" | O_BINARY"); - flags &= ~O_BINARY; -#endif - - if (flags) - printf_filtered (" | 0x%x", flags); - printf_filtered ("\n"); - } - -#ifdef PROCESS_GROUP_TYPE - printf_filtered ("Process group = %d\n", inferior_process_group); -#endif - - SERIAL_PRINT_TTY_STATE (stdin_serial, inferior_ttystate); -} - -/* NEW_TTY_PREFORK is called before forking a new child process, - so we can record the state of ttys in the child to be formed. - TTYNAME is null if we are to share the terminal with gdb; - or points to a string containing the name of the desired tty. - - NEW_TTY is called in new child processes under Unix, which will - become debugger target processes. This actually switches to - the terminal specified in the NEW_TTY_PREFORK call. */ - -void -new_tty_prefork (ttyname) - char *ttyname; -{ - /* Save the name for later, for determining whether we and the child - are sharing a tty. */ - inferior_thisrun_terminal = ttyname; -} - -void -new_tty () -{ - register int tty; - - if (inferior_thisrun_terminal == 0) - return; -#if !defined(__GO32__) -#ifdef TIOCNOTTY - /* Disconnect the child process from our controlling terminal. On some - systems (SVR4 for example), this may cause a SIGTTOU, so temporarily - ignore SIGTTOU. */ - tty = open("/dev/tty", O_RDWR); - if (tty > 0) - { - void (*osigttou) (); - - osigttou = (void (*)()) signal(SIGTTOU, SIG_IGN); - ioctl(tty, TIOCNOTTY, 0); - close(tty); - signal(SIGTTOU, osigttou); - } -#endif - - /* Now open the specified new terminal. */ - -#ifdef USE_O_NOCTTY - tty = open(inferior_thisrun_terminal, O_RDWR | O_NOCTTY); -#else - tty = open(inferior_thisrun_terminal, O_RDWR); -#endif - if (tty == -1) - { - print_sys_errmsg (inferior_thisrun_terminal, errno); - _exit(1); - } - - /* Avoid use of dup2; doesn't exist on all systems. */ - if (tty != 0) - { close (0); dup (tty); } - if (tty != 1) - { close (1); dup (tty); } - if (tty != 2) - { close (2); dup (tty); } - if (tty > 2) - close(tty); -#endif /* !go32 */ -} - -/* Kill the inferior process. Make us have no inferior. */ - -/* ARGSUSED */ -static void -kill_command (arg, from_tty) - char *arg; - int from_tty; -{ - /* Shouldn't this be target_has_execution? FIXME. */ - if (inferior_pid == 0) - error ("The program is not being run."); - if (!query ("Kill the program being debugged? ")) - error ("Not confirmed."); - target_kill (); - - init_thread_list(); /* Destroy thread info */ - - /* Killing off the inferior can leave us with a core file. If so, - print the state we are left in. */ - if (target_has_stack) { - printf_filtered ("In %s,\n", current_target->to_longname); - if (selected_frame == NULL) - fputs_filtered ("No selected stack frame.\n", gdb_stdout); - else - print_stack_frame (selected_frame, selected_frame_level, 1); - } -} - -/* Call set_sigint_trap when you need to pass a signal on to an attached - process when handling SIGINT */ - -/* ARGSUSED */ -static void -pass_signal (signo) - int signo; -{ - kill (inferior_pid, SIGINT); -} - -static void (*osig)(); - -void -set_sigint_trap() -{ - osig = (void (*) ()) signal (SIGINT, pass_signal); -} - -void -clear_sigint_trap() -{ - signal (SIGINT, osig); -} - -#if defined (SIGIO) && defined (FASYNC) && defined (FD_SET) && defined (F_SETOWN) -static void (*old_sigio) (); - -static void -handle_sigio (signo) - int signo; -{ - int numfds; - fd_set readfds; - - signal (SIGIO, handle_sigio); - - FD_ZERO (&readfds); - FD_SET (target_activity_fd, &readfds); - numfds = select (target_activity_fd + 1, &readfds, NULL, NULL, NULL); - if (numfds >= 0 && FD_ISSET (target_activity_fd, &readfds)) - { - if ((*target_activity_function) ()) - kill (inferior_pid, SIGINT); - } -} - -static int old_fcntl_flags; - -void -set_sigio_trap () -{ - if (target_activity_function) - { - old_sigio = (void (*) ()) signal (SIGIO, handle_sigio); - fcntl (target_activity_fd, F_SETOWN, getpid()); - old_fcntl_flags = fcntl (target_activity_fd, F_GETFL, 0); - fcntl (target_activity_fd, F_SETFL, old_fcntl_flags | FASYNC); - } -} - -void -clear_sigio_trap () -{ - if (target_activity_function) - { - signal (SIGIO, old_sigio); - fcntl (target_activity_fd, F_SETFL, old_fcntl_flags); - } -} -#else /* No SIGIO. */ -void -set_sigio_trap () -{ - if (target_activity_function) - abort (); -} - -void -clear_sigio_trap () -{ - if (target_activity_function) - abort (); -} -#endif /* No SIGIO. */ - - -/* This is here because this is where we figure out whether we (probably) - have job control. Just using job_control only does part of it because - setpgid or setpgrp might not exist on a system without job control. - It might be considered misplaced (on the other hand, process groups and - job control are closely related to ttys). - - For a more clean implementation, in libiberty, put a setpgid which merely - calls setpgrp and a setpgrp which does nothing (any system with job control - will have one or the other). */ -int -gdb_setpgid () -{ - int retval = 0; - - if (job_control) - { -#if defined (NEED_POSIX_SETPGID) || defined (HAVE_TERMIOS) - /* Do all systems with termios have setpgid? I hope so. */ - /* setpgid (0, 0) is supposed to work and mean the same thing as - this, but on Ultrix 4.2A it fails with EPERM (and - setpgid (getpid (), getpid ()) succeeds). */ - retval = setpgid (getpid (), getpid ()); -#else -#if defined (TIOCGPGRP) -#if defined(USG) && !defined(SETPGRP_ARGS) - retval = setpgrp (); -#else - retval = setpgrp (getpid (), getpid ()); -#endif /* USG */ -#endif /* TIOCGPGRP. */ -#endif /* NEED_POSIX_SETPGID */ - } - return retval; -} - -void -_initialize_inflow () -{ - add_info ("terminal", term_info, - "Print inferior's saved terminal status."); - - add_com ("kill", class_run, kill_command, - "Kill execution of program being debugged."); - - inferior_pid = 0; - - terminal_is_ours = 1; - - /* OK, figure out whether we have job control. If neither termios nor - sgtty (i.e. termio or go32), leave job_control 0. */ - -#if defined (HAVE_TERMIOS) - /* Do all systems with termios have the POSIX way of identifying job - control? I hope so. */ -#ifdef _POSIX_JOB_CONTROL - job_control = 1; -#else - job_control = sysconf (_SC_JOB_CONTROL); -#endif -#endif /* termios */ - -#ifdef HAVE_SGTTY -#ifdef TIOCGPGRP - job_control = 1; -#else - job_control = 0; -#endif /* TIOCGPGRP */ -#endif /* sgtty */ -} diff --git a/gnu/usr.bin/gdb/gdb/infptrace.c b/gnu/usr.bin/gdb/gdb/infptrace.c deleted file mode 100644 index 05f448c..0000000 --- a/gnu/usr.bin/gdb/gdb/infptrace.c +++ /dev/null @@ -1,507 +0,0 @@ -/* Low level Unix child interface to ptrace, for GDB when running under Unix. - Copyright 1988, 1989, 1990, 1991, 1992, 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. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" - -#ifdef USG -#include -#endif - -#include -#include -#include - -#ifndef NO_PTRACE_H -#ifdef PTRACE_IN_WRONG_PLACE -#include -#else -#include -#endif -#endif /* NO_PTRACE_H */ - -#if !defined (PT_KILL) -#define PT_KILL 8 -#endif - -#if !defined (PT_STEP) -#define PT_STEP 9 -#define PT_CONTINUE 7 -#define PT_READ_U 3 -#define PT_WRITE_U 6 -#define PT_READ_I 1 -#define PT_READ_D 2 -#define PT_WRITE_I 4 -#define PT_WRITE_D 5 -#endif /* No PT_STEP. */ - -#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 -#endif -#if 0 -/* Don't think this is used anymore. On the sequent (not sure whether it's - dynix or ptx or both), it is included unconditionally by sys/user.h and - not protected against multiple inclusion. */ -#include -#endif - -#if !defined (FETCH_INFERIOR_REGISTERS) -#include /* Probably need to poke the user structure */ -#if defined (KERNEL_U_ADDR_BSD) -#include /* For struct nlist */ -#endif /* KERNEL_U_ADDR_BSD. */ -#endif /* !FETCH_INFERIOR_REGISTERS */ - - -/* This function simply calls ptrace with the given arguments. - It exists so that all calls to ptrace are isolated in this - machine-dependent file. */ -int -call_ptrace (request, pid, addr, data) - int request, pid; - PTRACE_ARG3_TYPE addr; - int data; -{ - return 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 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 - -void -kill_inferior () -{ - 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); - ptrace (PT_KILL, inferior_pid, (PTRACE_ARG3_TYPE) 0, 0); - wait ((int *)0); - target_mourn_inferior (); -} - -#ifndef CHILD_RESUME - -/* Resume execution of the inferior process. - If STEP is nonzero, single-step it. - If SIGNAL is nonzero, give it that signal. */ - -void -child_resume (pid, step, signal) - int pid; - int step; - enum target_signal signal; -{ - errno = 0; - - if (pid == -1) - /* Resume all threads. */ - /* I think this only gets used in the non-threaded case, where "resume - all threads" and "resume inferior_pid" are the same. */ - pid = inferior_pid; - - /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace 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) - 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)); - - if (errno) - perror_with_name ("ptrace"); -} -#endif /* CHILD_RESUME */ - - -#ifdef ATTACH_DETACH -#include -/* Start debugging the process whose number is PID. */ -int -attach (pid) - int pid; -{ -#if defined(BSD4_4) && BSD >= 199306 - char procfile[MAXPATHLEN]; - int fd; - - sprintf(procfile, "/proc/%d/ctl", pid); - fd = open(procfile, O_WRONLY, 0); - - if (fd < 0) { - perror_with_name ("open"); - } - - /* send attach message to the process */ - if (write (fd, "attach", 7) < 0) { - close(fd); - perror_with_name ("write:attach"); - } - /* wait for the process to stop */ -#if 0 - if (write (fd, "wait", 5) < 0) { - close(fd); - perror_with_name ("write:wait"); - } -#endif - close (fd); -#else - errno = 0; - ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0); - if (errno) - perror_with_name ("ptrace"); -#endif - attach_flag = 1; - return pid; -} - -/* 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; -{ -#if defined(BSD4_4) && BSD >= 199306 - char procfile[MAXPATHLEN]; - int fd; - - sprintf(procfile, "/proc/%d/ctl", inferior_pid); - fd = open(procfile, O_WRONLY, 0); - - if (fd < 0) { - perror_with_name ("open"); - } - /* send detach message to the process */ - if (write (fd, "detach", 7) < 0) { - close(fd); - perror_with_name ("write:detach"); - } - /* TODO signals */ - close (fd); -#else - errno = 0; - ptrace (PT_DETACH, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal); - if (errno) - perror_with_name ("ptrace"); -#endif - attach_flag = 0; -} -#endif /* ATTACH_DETACH */ - -/* Default the type of the ptrace transfer to int. */ -#ifndef PTRACE_XFER_TYPE -#define PTRACE_XFER_TYPE int -#endif - -/* KERNEL_U_ADDR is the amount to subtract from u.u_ar0 - to get the offset in the core file of the register values. */ -#if defined (KERNEL_U_ADDR_BSD) && !defined (FETCH_INFERIOR_REGISTERS) -/* Get kernel_u_addr using BSD-style nlist(). */ -CORE_ADDR kernel_u_addr; -#endif /* KERNEL_U_ADDR_BSD. */ - -void -_initialize_kernel_u_addr () -{ -#if defined (KERNEL_U_ADDR_BSD) && !defined (FETCH_INFERIOR_REGISTERS) - struct nlist names[2]; - - names[0].n_un.n_name = "_u"; - names[1].n_un.n_name = NULL; - if (nlist ("/vmunix", names) == 0) - kernel_u_addr = names[0].n_value; - else - fatal ("Unable to get kernel u area address."); -#endif /* KERNEL_U_ADDR_BSD. */ -} - -#if !defined (FETCH_INFERIOR_REGISTERS) - -#if !defined (offsetof) -#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) -#endif - -/* U_REGS_OFFSET is the offset of the registers within the u area. */ -#if !defined (U_REGS_OFFSET) -#define U_REGS_OFFSET \ - ptrace (PT_READ_U, inferior_pid, \ - (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \ - - KERNEL_U_ADDR -#endif - -/* Registers we shouldn't try to fetch. */ -#if !defined (CANNOT_FETCH_REGISTER) -#define CANNOT_FETCH_REGISTER(regno) 0 -#endif - -/* Fetch one register. */ - -static void -fetch_register (regno) - int 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; - - if (CANNOT_FETCH_REGISTER (regno)) - { - memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */ - supply_register (regno, buf); - return; - } - - offset = U_REGS_OFFSET; - - regaddr = register_addr (regno, offset); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - *(PTRACE_XFER_TYPE *) &buf[i] = ptrace (PT_READ_U, inferior_pid, - (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (PTRACE_XFER_TYPE); - if (errno != 0) - { - sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno); - perror_with_name (mess); - } - } - supply_register (regno, buf); -} - - -/* Fetch all registers, or just one, from the child process. */ - -void -fetch_inferior_registers (regno) - int regno; -{ - int numregs; - - if (regno == -1) - { - numregs = ARCH_NUM_REGS; - for (regno = 0; regno < numregs; regno++) - fetch_register (regno); - } - else - fetch_register (regno); -} - -/* Registers we shouldn't try to store. */ -#if !defined (CANNOT_STORE_REGISTER) -#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). */ - -void -store_inferior_registers (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; - - unsigned int offset = U_REGS_OFFSET; - - if (regno >= 0) - { - 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 *) ®isters[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); - } - } - else - { - numregs = ARCH_NUM_REGS; - for (regno = 0; regno < numregs; 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 *) ®isters[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); - } - } - } -} -#endif /* !defined (FETCH_INFERIOR_REGISTERS). */ - - -#if !defined (CHILD_XFER_MEMORY) -/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory - in the NEW_SUN_PTRACE 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 (PTRACE_XFER_TYPE); - /* Round ending address up; get number of longwords that makes. */ - register int count - = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) - / sizeof (PTRACE_XFER_TYPE); - /* Allocate buffer of that many longwords. */ - register PTRACE_XFER_TYPE *buffer - = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); - - if (write) - { - /* Fill start and end extra bytes of buffer with existing memory data. */ - - if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE)) { - /* Need part of initial word -- fetch it. */ - buffer[0] = ptrace (PT_READ_I, inferior_pid, (PTRACE_ARG3_TYPE) addr, - 0); - } - - if (count > 1) /* FIXME, avoid if even boundary */ - { - buffer[count - 1] - = ptrace (PT_READ_I, inferior_pid, - ((PTRACE_ARG3_TYPE) - (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE))), - 0); - } - - /* Copy data to be written over corresponding part of buffer */ - - memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), - myaddr, - len); - - /* Write the entire buffer. */ - - for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - 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; - ptrace (PT_WRITE_I, inferior_pid, (PTRACE_ARG3_TYPE) addr, - buffer[i]); - } - if (errno) - return 0; - } - } - else - { - /* Read all the longwords */ - for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - buffer[i] = ptrace (PT_READ_I, inferior_pid, - (PTRACE_ARG3_TYPE) addr, 0); - if (errno) - return 0; - QUIT; - } - - /* Copy appropriate bytes out of the buffer. */ - memcpy (myaddr, - (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), - len); - } - return len; -} -#endif /* !defined (CHILD_XFER_MEMORY). */ diff --git a/gnu/usr.bin/gdb/gdb/infrun.c b/gnu/usr.bin/gdb/gdb/infrun.c deleted file mode 100644 index b07b1fe..0000000 --- a/gnu/usr.bin/gdb/gdb/infrun.c +++ /dev/null @@ -1,2037 +0,0 @@ -/* Target-struct-independent code to start (run) and stop an inferior process. - Copyright 1986, 1987, 1988, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include -#include -#include "symtab.h" -#include "frame.h" -#include "inferior.h" -#include "breakpoint.h" -#include "wait.h" -#include "gdbcore.h" -#include "gdbcmd.h" -#include "target.h" -#include "thread.h" -#include "annotate.h" - -#include - -/* unistd.h is needed to #define X_OK */ -#ifdef USG -#include -#else -#include -#endif - -/* Prototypes for local functions */ - -static void -signals_info PARAMS ((char *, int)); - -static void -handle_command PARAMS ((char *, int)); - -static void sig_print_info PARAMS ((enum target_signal)); - -static void -sig_print_header PARAMS ((void)); - -static void -resume_cleanups PARAMS ((int)); - -static int -hook_stop_stub PARAMS ((char *)); - -/* 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 - from it. The return value is non-zero on success, zero otherwise. */ -#ifndef GET_LONGJMP_TARGET -#define GET_LONGJMP_TARGET(PC_ADDR) 0 -#endif - - -/* Some machines have trampoline code that sits between function callers - and the actual functions themselves. If this machine doesn't have - such things, disable their processing. */ -#ifndef SKIP_TRAMPOLINE_CODE -#define SKIP_TRAMPOLINE_CODE(pc) 0 -#endif - -/* For SVR4 shared libraries, each call goes through a small piece of - trampoline code in the ".plt" section. IN_SOLIB_TRAMPOLINE evaluates - to nonzero if we are current stopped in one of these. */ -#ifndef IN_SOLIB_TRAMPOLINE -#define IN_SOLIB_TRAMPOLINE(pc,name) 0 -#endif - -/* 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 - nullified instruction before returning control to the user so as to avoid - confusion. */ - -#ifndef INSTRUCTION_NULLIFIED -#define INSTRUCTION_NULLIFIED 0 -#endif - -/* Tables of how to react to signals; the user sets them. */ - -static unsigned char *signal_stop; -static unsigned char *signal_print; -static unsigned char *signal_program; - -#define SET_SIGS(nsigs,sigs,flags) \ - do { \ - int signum = (nsigs); \ - while (signum-- > 0) \ - if ((sigs)[signum]) \ - (flags)[signum] = 1; \ - } while (0) - -#define UNSET_SIGS(nsigs,sigs,flags) \ - do { \ - int signum = (nsigs); \ - while (signum-- > 0) \ - if ((sigs)[signum]) \ - (flags)[signum] = 0; \ - } while (0) - - -/* Command list pointer for the "stop" placeholder. */ - -static struct cmd_list_element *stop_command; - -/* Nonzero if breakpoints are now inserted in the inferior. */ - -static int breakpoints_inserted; - -/* Function inferior was in as of last step command. */ - -static struct symbol *step_start_function; - -/* Nonzero if we are expecting a trace trap and should proceed from it. */ - -static int trap_expected; - -/* Nonzero if the next time we try to continue the inferior, it will - step one instruction and generate a spurious trace trap. - This is used to compensate for a bug in HP-UX. */ - -static int trap_expected_after_continue; - -/* Nonzero means expecting a trace trap - and should stop the inferior and return silently when it happens. */ - -int stop_after_trap; - -/* Nonzero means expecting a trap and caller will handle it themselves. - It is used after attach, due to attaching to a process; - when running in the shell before the child program has been exec'd; - and when running some kinds of remote stuff (FIXME?). */ - -int stop_soon_quietly; - -/* Nonzero if proceed is being used for a "finish" command or a similar - situation when stop_registers should be saved. */ - -int proceed_to_finish; - -/* Save register contents here when about to pop a stack dummy frame, - if-and-only-if proceed_to_finish is set. - Thus this contains the return value from the called function (assuming - values are returned in a register). */ - -char stop_registers[REGISTER_BYTES]; - -/* Nonzero if program stopped due to error trying to insert breakpoints. */ - -static int breakpoints_failed; - -/* Nonzero after stop if current stack frame should be printed. */ - -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 */ - - -/* Things to clean up if we QUIT out of resume (). */ -/* ARGSUSED */ -static void -resume_cleanups (arg) - int arg; -{ - normal_stop (); -} - -/* 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 - we get a SIGINT random_signal, but for remote debugging and perhaps - other targets, that's not true). - - STEP nonzero if we should step (zero to continue instead). - SIG is the signal to give the inferior (zero for none). */ -void -resume (step, sig) - int step; - enum target_signal sig; -{ - struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0); - QUIT; - -#ifdef CANNOT_STEP_BREAKPOINT - /* Most targets can step a breakpoint instruction, thus executing it - normally. But if this one cannot, just continue and we will hit - it anyway. */ - if (step && breakpoints_inserted && breakpoint_here_p (read_pc ())) - 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 - - /* Handle any optimized stores to the inferior NOW... */ -#ifdef DO_DEFERRED_STORES - DO_DEFERRED_STORES; -#endif - - /* Install inferior's terminal modes. */ - target_terminal_inferior (); - - 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'. */ - -void -clear_proceed_status () -{ - trap_expected = 0; - step_range_start = 0; - step_range_end = 0; - step_frame_address = 0; - step_over_calls = -1; - stop_after_trap = 0; - stop_soon_quietly = 0; - proceed_to_finish = 0; - breakpoint_proceeded = 1; /* We're about to proceed... */ - - /* Discard any remaining commands or status from previous stop. */ - bpstat_clear (&stop_bpstat); -} - -/* Basic routine for continuing the program in various fashions. - - ADDR is the address to resume at, or -1 for resume where stopped. - SIGGNAL is the signal to give it, or 0 for none, - or -1 for act according to how it stopped. - STEP is nonzero if should trap after one instruction. - -1 means return after that and print nothing. - You should probably set various step_... variables - before calling here, if you are stepping. - - You should call clear_proceed_status before calling proceed. */ - -void -proceed (addr, siggnal, step) - CORE_ADDR addr; - enum target_signal siggnal; - int step; -{ - int oneproc = 0; - - if (step > 0) - step_start_function = find_pc_function (read_pc ()); - if (step < 0) - stop_after_trap = 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. */ - - if (breakpoint_here_p (read_pc ())) - oneproc = 1; - -#ifdef STEP_SKIPS_DELAY - /* 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) - && STEP_SKIPS_DELAY (read_pc ())) - oneproc = 1; -#endif /* STEP_SKIPS_DELAY */ - } - else - write_pc (addr); - -#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; -#endif /* PREPARE_TO_PROCEED */ - - if (trap_expected_after_continue) - { - /* If (step == 0), a trap will be automatically generated after - the first instruction is executed. Force step one - instruction to clear this condition. This should not occur - if step is nonzero, but it is harmless in that case. */ - oneproc = 1; - trap_expected_after_continue = 0; - } - - if (oneproc) - /* We will get a trace trap after one instruction. - Continue it automatically and insert breakpoints then. */ - trap_expected = 1; - else - { - int temp = insert_breakpoints (); - if (temp) - { - print_sys_errmsg ("ptrace", temp); - error ("Cannot insert breakpoints.\n\ -The same program may be running in another process."); - } - breakpoints_inserted = 1; - } - - if (siggnal != TARGET_SIGNAL_DEFAULT) - stop_signal = siggnal; - /* If this signal should not be seen by program, - give it zero. Used for debugging signals. */ - else if (!signal_program[stop_signal]) - stop_signal = TARGET_SIGNAL_0; - - annotate_starting (); - - /* Resume inferior. */ - resume (oneproc || step || bpstat_should_step (), stop_signal); - - /* Wait for it to stop (if not standalone) - and in any case decode why it stopped, and act accordingly. */ - - wait_for_inferior (); - normal_stop (); -} - -/* Record the pc and sp of the program the last time it stopped. - These are just used internally by wait_for_inferior, but need - to be preserved over calls to it and cleared when the inferior - is started. */ -static CORE_ADDR prev_pc; -static CORE_ADDR prev_sp; -static CORE_ADDR prev_func_start; -static char *prev_func_name; -static CORE_ADDR prev_frame_address; - - -/* Start remote-debugging of a machine over a serial link. */ - -void -start_remote () -{ - init_wait_for_inferior (); - clear_proceed_status (); - stop_soon_quietly = 1; - trap_expected = 0; - wait_for_inferior (); - normal_stop (); -} - -/* Initialize static vars when a new inferior begins. */ - -void -init_wait_for_inferior () -{ - /* These are meaningless until the first time through wait_for_inferior. */ - prev_pc = 0; - prev_sp = 0; - prev_func_start = 0; - prev_func_name = NULL; - prev_frame_address = 0; - - trap_expected_after_continue = 0; - breakpoints_inserted = 0; - breakpoint_init_inferior (); - - /* Don't confuse first call to proceed(). */ - stop_signal = TARGET_SIGNAL_0; -} - -static void -delete_breakpoint_current_contents (arg) - PTR arg; -{ - struct breakpoint **breakpointp = (struct breakpoint **)arg; - if (*breakpointp != NULL) - delete_breakpoint (*breakpointp); -} - -/* 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. */ - -void -wait_for_inferior () -{ - struct cleanup *old_cleanups; - struct target_waitstatus w; - int another_trap; - int random_signal; - CORE_ADDR stop_sp = 0; - CORE_ADDR stop_func_start; - CORE_ADDR stop_func_end; - char *stop_func_name; - CORE_ADDR prologue_pc = 0, tmp; - struct symtab_and_line sal; - int remove_breakpoints_on_following_step = 0; - 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; - - 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); - current_line = sal.line; - current_symtab = sal.symtab; - - /* Are we stepping? */ -#define CURRENTLY_STEPPING() \ - ((through_sigtramp_breakpoint == NULL \ - && !handling_longjmp \ - && ((step_range_end && step_resume_breakpoint == NULL) \ - || trap_expected)) \ - || bpstat_should_step ()) - - while (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 - critical registers as part of their normal status mechanism. */ - - registers_changed (); - - pid = target_wait (-1, &w); - - flush_cached_frames (); - - /* If it's a new process, add it to the thread database */ - - if (pid != inferior_pid - && !in_thread_list (pid)) - { - 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. */ - - target_resume (-1, 0, TARGET_SIGNAL_0); - continue; - } - - switch (w.kind) - { - case TARGET_WAITKIND_LOADED: - /* Ignore it gracefully. */ - if (breakpoints_inserted) - { - mark_breakpoints_out (); - insert_breakpoints (); - } - resume (0, TARGET_SIGNAL_0); - continue; - - case TARGET_WAITKIND_SPURIOUS: - resume (0, TARGET_SIGNAL_0); - continue; - - case TARGET_WAITKIND_EXITED: - 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); - else - printf_filtered ("\nProgram exited normally.\n"); - gdb_flush (gdb_stdout); - target_mourn_inferior (); -#ifdef NO_SINGLE_STEP - one_stepped = 0; -#endif - stop_print_frame = 0; - goto stop_stepping; - - case TARGET_WAITKIND_SIGNALLED: - stop_print_frame = 0; - stop_signal = w.value.sig; - target_terminal_ours (); /* Must do this before mourn anyway */ - annotate_signalled (); - target_kill (); /* kill mourns as well */ - printf_filtered ("\nProgram terminated with signal "); - annotate_signal_name (); - printf_filtered ("%s", target_signal_to_name (stop_signal)); - annotate_signal_name_end (); - printf_filtered (", "); - annotate_signal_string (); - printf_filtered ("%s", target_signal_to_string (stop_signal)); - annotate_signal_string_end (); - printf_filtered (".\n"); - - printf_filtered ("The program no longer exists.\n"); - gdb_flush (gdb_stdout); -#ifdef NO_SINGLE_STEP - one_stepped = 0; -#endif - goto stop_stepping; - - case TARGET_WAITKIND_STOPPED: - /* This is the only case in which we keep going; the above cases - end in a continue or goto. */ - break; - } - - stop_signal = w.value.sig; - - stop_pc = read_pc_pid (pid); - - /* See if a thread hit a thread-specific breakpoint that was meant for - 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)) - { - random_signal = 0; - if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid)) - { - /* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */ - write_pc (stop_pc - DECR_PC_AFTER_BREAK); - - remove_breakpoints (); - target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */ - /* FIXME: What if a signal arrives instead of the single-step - happening? */ - target_wait (pid, &w); - insert_breakpoints (); - target_resume (pid, 0, TARGET_SIGNAL_0); - continue; - } - } - else - random_signal = 1; - - /* 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. */ - - if (pid != inferior_pid) - { - int printed = 0; - - /* If it's a random signal for a non-current thread, notify user - if he's expressed an interest. */ - - if (random_signal - && signal_print[stop_signal]) - { - 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); - } - - /* If it's not SIGTRAP and not a signal we want to stop for, then - continue the thread. */ - - if (stop_signal != TARGET_SIGNAL_TRAP - && !signal_stop[stop_signal]) - { - if (printed) - target_terminal_inferior (); - - /* Clear the signal if it should not be passed. */ - if (signal_program[stop_signal] == 0) - stop_signal = TARGET_SIGNAL_0; - - target_resume (pid, 0, stop_signal); - continue; - } - - /* It's a SIGTRAP or a signal we're interested in. Switch threads, - and fall into the rest of wait_for_inferior(). */ - - inferior_pid = pid; - printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid)); - - flush_cached_frames (); - trap_expected = 0; - if (step_resume_breakpoint) - { - delete_breakpoint (step_resume_breakpoint); - step_resume_breakpoint = NULL; - } - - /* Not sure whether we need to blow this away too, - but probably it is like the step-resume - breakpoint. */ - if (through_sigtramp_breakpoint) - { - delete_breakpoint (through_sigtramp_breakpoint); - through_sigtramp_breakpoint = NULL; - } - prev_pc = 0; - prev_sp = 0; - prev_func_name = NULL; - step_range_start = 0; - step_range_end = 0; - step_frame_address = 0; - handling_longjmp = 0; - another_trap = 0; - } - -#ifdef NO_SINGLE_STEP - if (one_stepped) - single_step (0); /* This actually cleans up the ss */ -#endif /* NO_SINGLE_STEP */ - - /* 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 (INSTRUCTION_NULLIFIED) - { - resume (1, 0); - continue; - } - - set_current_frame (create_new_frame (read_fp (), stop_pc)); - select_frame (get_current_frame (), 0); - -#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) - single step over a watchpoint without disabling the watchpoint. */ - if (STOPPED_BY_WATCHPOINT (w)) - { - resume (1, 0); - continue; - } -#endif - -#ifdef HAVE_NONSTEPPABLE_WATCHPOINT - /* It is far more common to need to disable a watchpoint - to step the inferior over it. FIXME. What else might - a debug register or page protection watchpoint scheme need - here? */ - if (STOPPED_BY_WATCHPOINT (w)) - { - remove_breakpoints (); - resume (1, 0); - - /* FIXME: This is bogus. You can't interact with the - inferior except when it is stopped. It apparently - happens to work on Irix4, but it depends on /proc - allowing us to muck with the memory of a running process, - and the kernel deciding to run one instruction of the - inferior before it executes our insert_breakpoints code, - which seems like an awfully dubious assumption. */ - insert_breakpoints (); - - continue; - } -#endif - -#ifdef HAVE_CONTINUABLE_WATCHPOINT - /* It may be possible to simply continue after a watchpoint. */ - STOPPED_BY_WATCHPOINT (w); -#endif - - stop_frame_address = FRAME_FP (get_current_frame ()); - stop_sp = read_sp (); - stop_func_start = 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. */ - find_pc_partial_function (stop_pc, &stop_func_name, &stop_func_start, - &stop_func_end); - stop_func_start += FUNCTION_START_OFFSET; - another_trap = 0; - bpstat_clear (&stop_bpstat); - stop_step = 0; - stop_stack_dummy = 0; - stop_print_frame = 1; - 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, - 2) drop through to start up again - (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) - { - stop_print_frame = 0; - break; - } - if (stop_soon_quietly) - break; - - /* Don't even think about breakpoints - if just proceeded over a breakpoint. - - However, if we are trying to proceed over a breakpoint - and end up in sigtramp, then through_sigtramp_breakpoint - will be set and we should check whether we've hit the - step breakpoint. */ - if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected - && through_sigtramp_breakpoint == NULL) - bpstat_clear (&stop_bpstat); - else - { - /* See if there is a breakpoint at the current PC. */ - stop_bpstat = bpstat_stop_status - (&stop_pc, stop_frame_address, -#if 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 */ - ); - /* Following in case break condition called a - function. */ - stop_print_frame = 1; - } - - if (stop_signal == TARGET_SIGNAL_TRAP) - random_signal - = !(bpstat_explains_signal (stop_bpstat) - || trap_expected -#ifndef CALL_DUMMY_BREAKPOINT_OFFSET - || PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address) -#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 - news) give another signal besides SIGTRAP, - so check here as well as above. */ -#ifndef CALL_DUMMY_BREAKPOINT_OFFSET - || PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address) -#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */ - ); - if (!random_signal) - stop_signal = TARGET_SIGNAL_TRAP; - } - } - else - random_signal = 1; - - /* For the program's own signals, act according to - the signal handling tables. */ - - if (random_signal) - { - /* Signal not for debugging purposes. */ - int printed = 0; - - stopped_by_random_signal = 1; - - if (signal_print[stop_signal]) - { - printed = 1; - target_terminal_ours_for_output (); - annotate_signal (); - printf_filtered ("\nProgram received signal "); - annotate_signal_name (); - printf_filtered ("%s", target_signal_to_name (stop_signal)); - annotate_signal_name_end (); - printf_filtered (", "); - annotate_signal_string (); - printf_filtered ("%s", target_signal_to_string (stop_signal)); - annotate_signal_string_end (); - printf_filtered (".\n"); - gdb_flush (gdb_stdout); - } - if (signal_stop[stop_signal]) - break; - /* If not going to stop, give terminal back - if we took it away. */ - else if (printed) - target_terminal_inferior (); - - /* Clear the signal if it should not be passed. */ - 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; - } - - /* Handle cases caused by hitting a breakpoint. */ - { - CORE_ADDR jmp_buf_pc; - struct bpstat_what what; - - what = bpstat_what (stop_bpstat); - - if (what.call_dummy) - { - stop_stack_dummy = 1; -#ifdef HP_OS_BUG - trap_expected_after_continue = 1; -#endif - } - - switch (what.main_action) - { - case BPSTAT_WHAT_SET_LONGJMP_RESUME: - /* 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(); - remove_breakpoints (); - breakpoints_inserted = 0; - if (!GET_LONGJMP_TARGET(&jmp_buf_pc)) goto keep_going; - - /* Need to blow away step-resume breakpoint, as it - interferes with us */ - if (step_resume_breakpoint != NULL) - { - delete_breakpoint (step_resume_breakpoint); - step_resume_breakpoint = NULL; - } - /* Not sure whether we need to blow this away too, but probably - it is like the step-resume breakpoint. */ - if (through_sigtramp_breakpoint != NULL) - { - delete_breakpoint (through_sigtramp_breakpoint); - through_sigtramp_breakpoint = NULL; - } - -#if 0 - /* FIXME - Need to implement nested temporary breakpoints */ - if (step_over_calls > 0) - 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 */ - goto keep_going; - - case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME: - case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE: - remove_breakpoints (); - breakpoints_inserted = 0; -#if 0 - /* FIXME - Need to implement nested temporary breakpoints */ - if (step_over_calls - && (stop_frame_address - INNER_THAN step_frame_address)) - { - another_trap = 1; - goto keep_going; - } -#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 (); - breakpoints_inserted = 0; - another_trap = 1; - /* Still need to check other stuff, at least the case - where we are stepping and step out of the right range. */ - break; - - case BPSTAT_WHAT_STOP_NOISY: - stop_print_frame = 1; - - /* We are about to nuke the step_resume_breakpoint and - through_sigtramp_breakpoint via the cleanup chain, so - no need to worry about it here. */ - - goto stop_stepping; - - case BPSTAT_WHAT_STOP_SILENT: - stop_print_frame = 0; - - /* We are about to nuke the step_resume_breakpoint and - through_sigtramp_breakpoint via the cleanup chain, so - no need to worry about it here. */ - - goto stop_stepping; - - case BPSTAT_WHAT_STEP_RESUME: - delete_breakpoint (step_resume_breakpoint); - step_resume_breakpoint = NULL; - break; - - case BPSTAT_WHAT_THROUGH_SIGTRAMP: - delete_breakpoint (through_sigtramp_breakpoint); - through_sigtramp_breakpoint = NULL; - - /* If were waiting for a trap, hitting the step_resume_break - doesn't count as getting it. */ - if (trap_expected) - another_trap = 1; - break; - - case BPSTAT_WHAT_LAST: - /* Not a real code, but listed here to shut up gcc -Wall. */ - - case BPSTAT_WHAT_KEEP_CHECKING: - break; - } - } - - /* We come here if we hit a breakpoint but should not - stop for it. Possibly we also were stepping - and should stop for that. So fall through and - test for stepping. But, if not stepping, - do not stop. */ - -#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 - handled above. As soon as we can test it on all of them, all - architectures should define it. */ - - /* If this is the breakpoint at the end of a stack dummy, - 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, stop_sp, stop_frame_address) - && !step_range_end) - { - stop_print_frame = 0; - stop_stack_dummy = 1; -#ifdef HP_OS_BUG - trap_expected_after_continue = 1; -#endif - break; - } -#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */ - - if (step_resume_breakpoint) - /* Having a step-resume breakpoint overrides anything - else having to do with stepping commands until - that breakpoint is reached. */ - /* I'm not sure whether this needs to be check_sigtramp2 or - whether it could/should be keep_going. */ - goto check_sigtramp2; - - if (step_range_end == 0) - /* Likewise if we aren't even stepping. */ - /* I'm not sure whether this needs to be check_sigtramp2 or - whether it could/should be keep_going. */ - goto check_sigtramp2; - - /* If stepping through a line, keep going if still within it. */ - if (stop_pc >= step_range_start - && stop_pc < step_range_end - /* 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 - && stop_frame_address - && (stop_sp INNER_THAN prev_sp - || stop_frame_address != step_frame_address))) - { - /* We might be doing a BPSTAT_WHAT_SINGLE and getting a signal. - So definately need to check for sigtramp here. */ - goto check_sigtramp2; - } - - /* We stepped out of the stepping range. See if that was due - to a subroutine call that we should proceed to the end of. */ - - /* Did we just take a signal? */ - if (IN_SIGTRAMP (stop_pc, stop_func_name) - && !IN_SIGTRAMP (prev_pc, prev_func_name)) - { - /* 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 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; - - sr_sal.pc = prev_pc; - sr_sal.symtab = NULL; - sr_sal.line = 0; - /* We could probably be setting the frame to - prev_frame_address; the reason we don't is that it didn't used - to exist. */ - step_resume_breakpoint = - set_momentary_breakpoint (sr_sal, NULL, bp_step_resume); - if (breakpoints_inserted) - insert_breakpoints (); - } - - /* If this is stepi or nexti, make sure that the stepping range - gets us past that instruction. */ - if (step_range_end == 1) - /* FIXME: Does this run afoul of the code below which, if - we step into the middle of a line, resets the stepping - range? */ - step_range_end = (step_range_start = prev_pc) + 1; - - remove_breakpoints_on_following_step = 1; - goto keep_going; - } - -#if 1 - if (stop_func_start) - { - struct symtab *s; - - /* Do this after the IN_SIGTRAMP check; it might give - an error. */ - prologue_pc = stop_func_start; - - /* Don't skip the prologue if this is assembly source */ - s = find_pc_symtab (stop_pc); - if (s && s->language != language_asm) - 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 - || stop_sp != prev_sp) - && (/* PC is completely out of bounds of any known objfiles. Treat - like a subroutine call. */ - ! 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 - 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 - - /* ...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 - - /* 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 - 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_TRAMPOLINE (stop_pc, stop_func_name) - - /* 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 is experimental code which greatly simplifies the subroutine call - test. I've actually tested on the Alpha, and it works great. -Stu */ - - if (in_prologue (stop_pc, NULL) - || (prev_func_start != 0 - && stop_func_start == 0)) -#endif - { - /* It's a subroutine call. */ - - if (step_over_calls == 0) - { - /* I presume that step_over_calls is only 0 when we're - supposed to be stepping at the assembly language level - ("stepi"). Just stop. */ - stop_step = 1; - break; - } - - if (step_over_calls > 0) - /* We're doing a "next". */ - goto step_over_function; - - /* If we are in a function call trampoline (a stub between - the calling routine and the real function), locate the real - function. That's what tells us (a) whether we want to step - into it at all, and (b) what prologue we want to run to - the end of, if we do step into it. */ - tmp = SKIP_TRAMPOLINE_CODE (stop_pc); - if (tmp != 0) - stop_func_start = tmp; - - /* If we have line number information for the function we - are thinking of stepping into, step into it. - - If there are several symtabs at that PC (e.g. with include - files), just want to know whether *any* of them have line - numbers. find_pc_line handles this. */ - { - struct symtab_and_line tmp_sal; - - tmp_sal = find_pc_line (stop_func_start, 0); - if (tmp_sal.line != 0) - goto step_into_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 ())); - sr_sal.symtab = NULL; - sr_sal.line = 0; - step_resume_breakpoint = - set_momentary_breakpoint (sr_sal, get_current_frame (), - bp_step_resume); - step_resume_breakpoint->frame = prev_frame_address; - if (breakpoints_inserted) - insert_breakpoints (); - } - goto keep_going; - -step_into_function: - /* Subroutine call with source code we should not step over. - Do step to the first line of code in it. */ - { - struct symtab *s; - - s = find_pc_symtab (stop_pc); - if (s && s->language != language_asm) - SKIP_PROLOGUE (stop_func_start); - } - sal = find_pc_line (stop_func_start, 0); - /* Use the step_resume_break to step until - the end of the prologue, even if that involves jumps - (as it seems to on the vax under 4.2). */ - /* If the prologue ends in the middle of a source line, - continue to the end of that source line (if it is still - within the function). Otherwise, just go to end of prologue. */ -#ifdef PROLOGUE_FIRSTLINE_OVERLAP - /* no, don't either. It skips any code that's - legitimately on the first line. */ -#else - if (sal.end && sal.pc != stop_func_start && sal.end < stop_func_end) - stop_func_start = sal.end; -#endif - - if (stop_func_start == stop_pc) - { - /* We are already there: stop now. */ - stop_step = 1; - break; - } - else - /* Put the step-breakpoint there and go until there. */ - { - struct symtab_and_line sr_sal; - - sr_sal.pc = stop_func_start; - sr_sal.symtab = NULL; - sr_sal.line = 0; - /* 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. */ - step_resume_breakpoint = - set_momentary_breakpoint (sr_sal, NULL, bp_step_resume); - if (breakpoints_inserted) - insert_breakpoints (); - - /* And make sure stepping stops right away then. */ - step_range_end = step_range_start; - } - goto keep_going; - } - - /* We've wandered out of the step range. */ - - sal = find_pc_line(stop_pc, 0); - - if (step_range_end == 1) - { - /* It is stepi or nexti. We always want to stop stepping after - one instruction. */ - stop_step = 1; - break; - } - - if (sal.line == 0) - { - /* We have no line number information. That means to stop - stepping (does this always happen right after one instruction, - when we do "s" in a function with no line numbers, - or can this happen as a result of a return or longjmp?). */ - stop_step = 1; - break; - } - - 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 - we don't stop if we step into the middle of a different line. - That is said to make things like for (;;) statements work - better. */ - stop_step = 1; - break; - } - - /* We aren't done stepping. - - 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 - things like for(;;) statements work better.) */ - - if (stop_func_end && sal.end >= stop_func_end) - { - /* If this is the last line of the function, don't keep stepping - (it would probably step us out of the function). - This is particularly necessary for a one-line function, - in which after skipping the prologue we better stop even though - we will be in mid-line. */ - stop_step = 1; - break; - } - step_range_start = sal.pc; - step_range_end = sal.end; - goto keep_going; - - check_sigtramp2: - if (trap_expected - && IN_SIGTRAMP (stop_pc, stop_func_name) - && !IN_SIGTRAMP (prev_pc, prev_func_name)) - { - /* What has happened here is that we have just stepped the inferior - with a signal (because it is a signal which shouldn't make - us stop), thus stepping into sigtramp. - - So we need to set a step_resume_break_address breakpoint - and continue until we hit it, and then step. FIXME: This should - be more enduring than a step_resume breakpoint; we should know - that we will later need to keep going rather than re-hitting - the breakpoint here (see testsuite/gdb.t06/signals.exp where - it says "exceedingly difficult"). */ - struct symtab_and_line sr_sal; - - sr_sal.pc = prev_pc; - sr_sal.symtab = NULL; - sr_sal.line = 0; - /* 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. */ - through_sigtramp_breakpoint = - set_momentary_breakpoint (sr_sal, NULL, bp_through_sigtramp); - if (breakpoints_inserted) - insert_breakpoints (); - - remove_breakpoints_on_following_step = 1; - another_trap = 1; - } - - keep_going: - /* Come to this label when you need to resume the inferior. - It's really much cleaner to do a goto than a maze of if-else - conditions. */ - - /* 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 - BREAK is defined, the - original pc would not have - been at the start of a - function. */ - prev_func_name = stop_func_name; - prev_sp = stop_sp; - prev_frame_address = stop_frame_address; - - /* If we did not do break;, it means we should keep - running the inferior and not return to debugger. */ - - if (trap_expected && stop_signal != TARGET_SIGNAL_TRAP) - { - /* We took a signal (which we are supposed to pass through to - the inferior, else we'd have done a break above) and we - haven't yet gotten our trap. Simply continue. */ - resume (CURRENTLY_STEPPING (), stop_signal); - } - else - { - /* Either the trap was not expected, but we are continuing - anyway (the user asked that this signal be passed to the - child) - -- or -- - The signal was SIGTRAP, e.g. it was our signal, but we - decided we should resume from it. - - We're going to run this baby now! - - Insert breakpoints now, unless we are trying - to one-proceed past a breakpoint. */ - /* If we've just finished a special step resume and we don't - want to hit a breakpoint, pull em out. */ - if (step_resume_breakpoint == NULL - && through_sigtramp_breakpoint == NULL - && remove_breakpoints_on_following_step) - { - remove_breakpoints_on_following_step = 0; - remove_breakpoints (); - breakpoints_inserted = 0; - } - else if (!breakpoints_inserted && - (through_sigtramp_breakpoint != NULL || !another_trap)) - { - breakpoints_failed = insert_breakpoints (); - if (breakpoints_failed) - break; - breakpoints_inserted = 1; - } - - trap_expected = another_trap; - - if (stop_signal == TARGET_SIGNAL_TRAP) - 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. */ - /* 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(); -#endif /* SHIFT_INST_REGS */ - - resume (CURRENTLY_STEPPING (), stop_signal); - } - } - - stop_stepping: - if (target_has_execution) - { - /* 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. */ - prev_pc = read_pc (); - prev_func_start = stop_func_start; - prev_func_name = stop_func_name; - prev_sp = stop_sp; - prev_frame_address = stop_frame_address; - } - do_cleanups (old_cleanups); -} - -/* Here to return control to GDB when the inferior stops for real. - Print appropriate messages, remove breakpoints, give terminal our modes. - - STOP_PRINT_FRAME nonzero means print the executing frame - (pc, function, args, file, line number and line text). - BREAKPOINTS_FAILED nonzero means stop was due to error - attempting to insert breakpoints. */ - -void -normal_stop () -{ - /* 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()) - (get_current_frame ())->pc = read_pc (); - - if (breakpoints_failed) - { - target_terminal_ours_for_output (); - print_sys_errmsg ("ptrace", breakpoints_failed); - printf_filtered ("Stopped; cannot insert breakpoints.\n\ -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"); - } - - breakpoints_inserted = 0; - - /* Delete the breakpoint we stopped at, if it wants to be deleted. - Delete any breakpoint that is to be deleted at the next stop. */ - - breakpoint_auto_delete (stop_bpstat); - - /* If an auto-display called a function and that got a signal, - delete that auto-display to avoid an infinite recursion. */ - - if (stopped_by_random_signal) - disable_current_display (); - - if (step_multi && stop_step) - goto done; - - target_terminal_ours (); - - /* Look up the hook_stop and run it if it exists. */ - - if (stop_command->hook) - { - catch_errors (hook_stop_stub, (char *)stop_command->hook, - "Error while running hook_stop:\n", RETURN_MASK_ALL); - } - - if (!target_has_stack) - goto done; - - /* 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) - { - if (stop_print_frame) - { - int source_only; - - source_only = bpstat_print (stop_bpstat); - source_only = source_only || - ( stop_step - && step_frame_address == stop_frame_address - && step_start_function == find_pc_function (stop_pc)); - - print_stack_frame (selected_frame, -1, source_only? -1: 1); - - /* Display the auto-display expressions. */ - do_displays (); - } - } - - /* Save the function value return registers, if we care. - We might be about to restore their previous contents. */ - if (proceed_to_finish) - read_register_bytes (0, stop_registers, REGISTER_BYTES); - - if (stop_stack_dummy) - { - /* Pop the empty frame that contains the stack dummy. - 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(); - select_frame (get_current_frame (), 0); - } - done: - annotate_stopped (); -} - -static int -hook_stop_stub (cmd) - char *cmd; -{ - execute_user_command ((struct cmd_list_element *)cmd, 0); - return (0); -} - -int signal_stop_state (signo) - int signo; -{ - return signal_stop[signo]; -} - -int signal_print_state (signo) - int signo; -{ - return signal_print[signo]; -} - -int signal_pass_state (signo) - int signo; -{ - return signal_program[signo]; -} - -static void -sig_print_header () -{ - printf_filtered ("\ -Signal Stop\tPrint\tPass to program\tDescription\n"); -} - -static void -sig_print_info (oursig) - enum target_signal oursig; -{ - char *name = target_signal_to_name (oursig); - printf_filtered ("%s", name); - printf_filtered ("%*.*s ", 13 - strlen (name), 13 - strlen (name), - " "); - printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No"); - printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No"); - printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No"); - printf_filtered ("%s\n", target_signal_to_string (oursig)); -} - -/* Specify how various signals in the inferior should be handled. */ - -static void -handle_command (args, from_tty) - char *args; - int from_tty; -{ - char **argv; - int digits, wordlen; - int sigfirst, signum, siglast; - enum target_signal oursig; - int allsigs; - int nsigs; - unsigned char *sigs; - struct cleanup *old_chain; - - if (args == NULL) - { - error_no_arg ("signal to handle"); - } - - /* Allocate and zero an array of flags for which signals to handle. */ - - nsigs = (int)TARGET_SIGNAL_LAST; - sigs = (unsigned char *) alloca (nsigs); - memset (sigs, 0, nsigs); - - /* Break the command line up into args. */ - - argv = buildargv (args); - if (argv == NULL) - { - nomem (0); - } - old_chain = make_cleanup (freeargv, (char *) argv); - - /* Walk through the args, looking for signal oursigs, signal names, and - actions. Signal numbers and signal names may be interspersed with - actions, with the actions being performed for all signals cumulatively - specified. Signal ranges can be specified as -. */ - - while (*argv != NULL) - { - wordlen = strlen (*argv); - for (digits = 0; isdigit ((*argv)[digits]); digits++) {;} - allsigs = 0; - sigfirst = siglast = -1; - - if (wordlen >= 1 && !strncmp (*argv, "all", wordlen)) - { - /* Apply action to all signals except those used by the - debugger. Silently skip those. */ - allsigs = 1; - sigfirst = 0; - siglast = nsigs - 1; - } - else if (wordlen >= 1 && !strncmp (*argv, "stop", wordlen)) - { - SET_SIGS (nsigs, sigs, signal_stop); - SET_SIGS (nsigs, sigs, signal_print); - } - else if (wordlen >= 1 && !strncmp (*argv, "ignore", wordlen)) - { - UNSET_SIGS (nsigs, sigs, signal_program); - } - else if (wordlen >= 2 && !strncmp (*argv, "print", wordlen)) - { - SET_SIGS (nsigs, sigs, signal_print); - } - else if (wordlen >= 2 && !strncmp (*argv, "pass", wordlen)) - { - SET_SIGS (nsigs, sigs, signal_program); - } - else if (wordlen >= 3 && !strncmp (*argv, "nostop", wordlen)) - { - UNSET_SIGS (nsigs, sigs, signal_stop); - } - else if (wordlen >= 3 && !strncmp (*argv, "noignore", wordlen)) - { - SET_SIGS (nsigs, sigs, signal_program); - } - else if (wordlen >= 4 && !strncmp (*argv, "noprint", wordlen)) - { - UNSET_SIGS (nsigs, sigs, signal_print); - UNSET_SIGS (nsigs, sigs, signal_stop); - } - else if (wordlen >= 4 && !strncmp (*argv, "nopass", wordlen)) - { - UNSET_SIGS (nsigs, sigs, signal_program); - } - 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 = atoi (*argv); - if ((*argv)[digits] == '-') - { - siglast = atoi ((*argv) + digits + 1); - } - if (sigfirst > siglast) - { - /* Bet he didn't figure we'd think of this case... */ - signum = sigfirst; - sigfirst = siglast; - siglast = signum; - } - if (sigfirst < 0 || sigfirst >= nsigs) - { - error ("Signal %d not in range 0-%d", sigfirst, nsigs - 1); - } - if (siglast < 0 || siglast >= nsigs) - { - error ("Signal %d not in range 0-%d", siglast, nsigs - 1); - } - } - else - { - oursig = target_signal_from_name (*argv); - if (oursig != TARGET_SIGNAL_UNKNOWN) - { - sigfirst = siglast = (int)oursig; - } - else - { - /* Not a number and not a recognized flag word => complain. */ - error ("Unrecognized or ambiguous flag word: \"%s\".", *argv); - } - } - - /* If any signal numbers or symbol names were found, set flags for - which signals to apply actions to. */ - - for (signum = sigfirst; signum >= 0 && signum <= siglast; 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\ -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; - default: - sigs[signum] = 1; - break; - } - } - - argv++; - } - - target_notice_signals(inferior_pid); - - if (from_tty) - { - /* Show the results. */ - sig_print_header (); - for (signum = 0; signum < nsigs; signum++) - { - if (sigs[signum]) - { - sig_print_info (signum); - } - } - } - - 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 - targets, all signals should be in the signal tables). */ - -static void -signals_info (signum_exp, from_tty) - char *signum_exp; - int from_tty; -{ - enum target_signal oursig; - sig_print_header (); - - if (signum_exp) - { - /* First see if this is a symbol name. */ - oursig = target_signal_from_name (signum_exp); - if (oursig == TARGET_SIGNAL_UNKNOWN) - { - /* Nope, maybe it's an address which evaluates to a signal - number. */ - /* 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. */ - int i = parse_and_eval_address (signum_exp); - if (i >= (int)TARGET_SIGNAL_LAST - || i < 0 - || i == (int)TARGET_SIGNAL_UNKNOWN - || i == (int)TARGET_SIGNAL_DEFAULT) - error ("Signal number out of bounds."); - oursig = (enum target_signal)i; - } - sig_print_info (oursig); - return; - } - - 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)) - { - QUIT; - - if (oursig != TARGET_SIGNAL_UNKNOWN - && oursig != TARGET_SIGNAL_DEFAULT - && oursig != TARGET_SIGNAL_0) - sig_print_info (oursig); - } - - printf_filtered ("\nUse the \"handle\" command to change these tables.\n"); -} - -/* Save all of the information associated with the inferior<==>gdb - connection. INF_STATUS is a pointer to a "struct inferior_status" - (defined in inferior.h). */ - -void -save_inferior_status (inf_status, restore_stack_info) - struct inferior_status *inf_status; - int restore_stack_info; -{ - inf_status->stop_signal = stop_signal; - inf_status->stop_pc = stop_pc; - inf_status->stop_frame_address = stop_frame_address; - inf_status->stop_step = stop_step; - inf_status->stop_stack_dummy = stop_stack_dummy; - inf_status->stopped_by_random_signal = stopped_by_random_signal; - inf_status->trap_expected = trap_expected; - inf_status->step_range_start = step_range_start; - inf_status->step_range_end = step_range_end; - inf_status->step_frame_address = step_frame_address; - 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. - 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; - stop_bpstat = bpstat_copy (stop_bpstat); - 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); - - record_selected_frame (&(inf_status->selected_frame_address), - &(inf_status->selected_level)); - return; -} - -struct restore_selected_frame_args { - FRAME_ADDR frame_address; - int level; -}; - -static int restore_selected_frame PARAMS ((char *)); - -/* Restore the selected frame. args is really a struct - restore_selected_frame_args * (declared as char * for catch_errors) - telling us what frame to restore. Returns 1 for success, or 0 for - failure. An error message will have been printed on error. */ -static int -restore_selected_frame (args) - char *args; -{ - struct restore_selected_frame_args *fr = - (struct restore_selected_frame_args *) args; - FRAME fid; - int level = fr->level; - - fid = find_relative_frame (get_current_frame (), &level); - - /* If inf_status->selected_frame_address is NULL, there was no - previously selected frame. */ - if (fid == 0 || - FRAME_FP (fid) != fr->frame_address || - level != 0) - { - warning ("Unable to restore previously selected frame.\n"); - return 0; - } - select_frame (fid, fr->level); - return(1); -} - -void -restore_inferior_status (inf_status) - struct inferior_status *inf_status; -{ - stop_signal = inf_status->stop_signal; - stop_pc = inf_status->stop_pc; - stop_frame_address = inf_status->stop_frame_address; - stop_step = inf_status->stop_step; - stop_stack_dummy = inf_status->stop_stack_dummy; - stopped_by_random_signal = inf_status->stopped_by_random_signal; - trap_expected = inf_status->trap_expected; - step_range_start = inf_status->step_range_start; - step_range_end = inf_status->step_range_end; - step_frame_address = inf_status->step_frame_address; - step_over_calls = inf_status->step_over_calls; - stop_after_trap = inf_status->stop_after_trap; - stop_soon_quietly = inf_status->stop_soon_quietly; - bpstat_clear (&stop_bpstat); - stop_bpstat = inf_status->stop_bpstat; - breakpoint_proceeded = inf_status->breakpoint_proceeded; - proceed_to_finish = inf_status->proceed_to_finish; - - memcpy (stop_registers, inf_status->stop_registers, REGISTER_BYTES); - - /* The inferior can be gone if the user types "print exit(0)" - (and perhaps other times). */ - if (target_has_execution) - write_register_bytes (0, inf_status->registers, REGISTER_BYTES); - - /* The inferior can be gone if the user types "print exit(0)" - (and perhaps other times). */ - - /* FIXME: If we are being called after stopping in a function which - is called from gdb, we should not be trying to restore the - selected frame; it just prints a spurious error message (The - message is useful, however, in detecting bugs in gdb (like if gdb - clobbers the stack)). In fact, should we be restoring the - inferior status at all in that case? . */ - - if (target_has_stack && inf_status->restore_stack_info) - { - struct restore_selected_frame_args fr; - fr.level = inf_status->selected_level; - fr.frame_address = inf_status->selected_frame_address; - /* The point of catch_errors is that if the stack is clobbered, - walking the stack might encounter a garbage pointer and error() - trying to dereference it. */ - if (catch_errors (restore_selected_frame, &fr, - "Unable to restore previously selected frame:\n", - RETURN_MASK_ERROR) == 0) - /* Error in restoring the selected frame. Select the innermost - frame. */ - select_frame (get_current_frame (), 0); - } -} - - -void -_initialize_infrun () -{ - register int i; - register int numsigs; - - add_info ("signals", signals_info, - "What debugger does when program gets various signals.\n\ -Specify a signal number as argument to print info on that signal only."); - add_info_alias ("handle", "signals", 0); - - add_com ("handle", class_run, handle_command, - "Specify how to handle a signal.\n\ -Args are signal numbers and actions to apply to those signals.\n\ -Signal numbers may be numeric (ex. 11) or symbolic (ex. SIGSEGV).\n\ -Numeric ranges may be specified with the form LOW-HIGH (ex. 14-21).\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\ -\"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."); - - 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 *) - xmalloc (sizeof (signal_stop[0]) * numsigs); - signal_print = (unsigned char *) - xmalloc (sizeof (signal_print[0]) * numsigs); - signal_program = (unsigned char *) - xmalloc (sizeof (signal_program[0]) * numsigs); - for (i = 0; i < numsigs; i++) - { - signal_stop[i] = 1; - signal_print[i] = 1; - signal_program[i] = 1; - } - - /* Signals caused by debugger's own actions - should not be given to the program afterwards. */ - signal_program[TARGET_SIGNAL_TRAP] = 0; - signal_program[TARGET_SIGNAL_INT] = 0; - - /* Signals that are not errors should not normally enter the debugger. */ - signal_stop[TARGET_SIGNAL_ALRM] = 0; - signal_print[TARGET_SIGNAL_ALRM] = 0; - signal_stop[TARGET_SIGNAL_VTALRM] = 0; - signal_print[TARGET_SIGNAL_VTALRM] = 0; - signal_stop[TARGET_SIGNAL_PROF] = 0; - signal_print[TARGET_SIGNAL_PROF] = 0; - signal_stop[TARGET_SIGNAL_CHLD] = 0; - signal_print[TARGET_SIGNAL_CHLD] = 0; - signal_stop[TARGET_SIGNAL_IO] = 0; - signal_print[TARGET_SIGNAL_IO] = 0; - signal_stop[TARGET_SIGNAL_POLL] = 0; - signal_print[TARGET_SIGNAL_POLL] = 0; - signal_stop[TARGET_SIGNAL_URG] = 0; - signal_print[TARGET_SIGNAL_URG] = 0; -} diff --git a/gnu/usr.bin/gdb/gdb/inftarg.c b/gnu/usr.bin/gdb/gdb/inftarg.c deleted file mode 100644 index 6515c26..0000000 --- a/gnu/usr.bin/gdb/gdb/inftarg.c +++ /dev/null @@ -1,328 +0,0 @@ -/* Target-vector operations for controlling Unix child processes, for GDB. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - Contributed by 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include "frame.h" /* required by inferior.h */ -#include "inferior.h" -#include "target.h" -#include "wait.h" -#include "gdbcore.h" -#include "command.h" -#include - -static void -child_prepare_to_store PARAMS ((void)); - -#ifndef CHILD_WAIT -static int child_wait PARAMS ((int, struct target_waitstatus *)); -#endif /* CHILD_WAIT */ - -static void child_open PARAMS ((char *, int)); - -static void -child_files_info PARAMS ((struct target_ops *)); - -static void -child_detach PARAMS ((char *, int)); - -static void -child_attach PARAMS ((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_mourn_inferior PARAMS ((void)); - -static int -child_can_run PARAMS ((void)); - -extern char **environ; - -/* Forward declaration */ -extern struct target_ops child_ops; - -#ifndef CHILD_WAIT - -/* Wait for child to do something. Return pid of child, or -1 in case - of error; store status through argument pointer OURSTATUS. */ - -static int -child_wait (pid, ourstatus) - int pid; - struct target_waitstatus *ourstatus; -{ - int save_errno; - int status; - - do { - if (attach_flag) - set_sigint_trap(); /* Causes SIGINT to be passed on to the - attached process. */ - set_sigio_trap (); - - pid = proc_wait (inferior_pid, &status); - save_errno = errno; - - clear_sigio_trap (); - - if (attach_flag) - clear_sigint_trap(); - - if (pid == -1) - { - 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 */ - store_waitstatus (ourstatus, status); - return pid; -} -#endif /* CHILD_WAIT */ - -/* Attach to process PID, then initialize for debugging it. */ - -static void -child_attach (args, from_tty) - char *args; - int from_tty; -{ - if (!args) - error_no_arg ("process-id to attach"); - -#ifndef ATTACH_DETACH - error ("Can't attach to a process on this machine."); -#else - { - char *exec_file; - int pid; - - pid = atoi (args); - - if (pid == getpid()) /* Trying to masturbate? */ - error ("I refuse to debug myself!"); - - if (from_tty) - { - exec_file = (char *) get_exec_file (0); - - 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); - inferior_pid = pid; - push_target (&child_ops); - } -#endif /* ATTACH_DETACH */ -} - - -/* 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; -{ -#ifdef ATTACH_DETACH - { - int siggnal = 0; - - if (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)); - gdb_flush (gdb_stdout); - } - if (args) - siggnal = atoi (args); - - detach (siggnal); - inferior_pid = 0; - unpush_target (&child_ops); - } -#else - error ("This version of Unix does not support detaching a process."); -#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 -child_prepare_to_store () -{ -#ifdef CHILD_PREPARE_TO_STORE - CHILD_PREPARE_TO_STORE (); -#endif -} - -/* Print status information about what we're accessing. */ - -static void -child_files_info (ignore) - struct target_ops *ignore; -{ - printf_unfiltered ("\tUsing the running image of %s %s.\n", - attach_flag? "attached": "child", target_pid_to_str (inferior_pid)); -} - -/* ARGSUSED */ -static void -child_open (arg, from_tty) - char *arg; - int from_tty; -{ - error ("Use the \"run\" command to start a Unix child process."); -} - -/* Stub function which causes the inferior that runs it, to be ptrace-able - by its parent process. */ - -static void -ptrace_me () -{ - /* "Trace me, Dr. Memory!" */ - call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0); -} - -/* Stub function which causes the GDB that runs it, to start ptrace-ing - the child process. */ - -static void -ptrace_him (pid) - int pid; -{ - push_target (&child_ops); - -#ifdef START_INFERIOR_TRAPS_EXPECTED - startup_inferior (START_INFERIOR_TRAPS_EXPECTED); -#else - /* One trap to exec the shell, one to exec the program being debugged. */ - startup_inferior (2); -#endif -} - -/* 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. - ENV is the environment vector to pass. Errors reported with error(). */ - -static void -child_create_inferior (exec_file, allargs, env) - char *exec_file; - char *allargs; - char **env; -{ - fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL); - /* We are at the first instruction we care about. */ - /* Pedal to the metal... */ - proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0); -} - -static void -child_mourn_inferior () -{ - unpush_target (&child_ops); - proc_remove_foreign (inferior_pid); - generic_mourn_inferior (); -} - -static int -child_can_run () -{ - return(1); -} - -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 */ - 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 */ -}; - -void -_initialize_inftarg () -{ - add_target (&child_ops); -} diff --git a/gnu/usr.bin/gdb/gdb/init.c b/gnu/usr.bin/gdb/gdb/init.c index 7606e3c..d3d83f4 100644 --- a/gnu/usr.bin/gdb/gdb/init.c +++ b/gnu/usr.bin/gdb/gdb/init.c @@ -1,4 +1,3 @@ -#include "defs.h" /* for KERNEL_DEBUG */ /* Do not modify this file. */ /* It is created automatically by the Makefile. */ void initialize_all_files () { @@ -8,6 +7,7 @@ void initialize_all_files () { {extern void _initialize_thread (); _initialize_thread ();} {extern void _initialize_source (); _initialize_source ();} {extern void _initialize_values (); _initialize_values ();} + {extern void _initialize_valops (); _initialize_valops ();} {extern void _initialize_valarith (); _initialize_valarith ();} {extern void _initialize_valprint (); _initialize_valprint ();} {extern void _initialize_printcmd (); _initialize_printcmd ();} @@ -19,21 +19,22 @@ void initialize_all_files () { {extern void _initialize_command (); _initialize_command ();} {extern void _initialize_gdbtypes (); _initialize_gdbtypes ();} {extern void _initialize_copying (); _initialize_copying ();} + {extern void _initialize_i386_tdep (); _initialize_i386_tdep ();} {extern void _initialize_solib (); _initialize_solib ();} {extern void _initialize_ser_hardwire (); _initialize_ser_hardwire ();} - {extern void _initialize_exec (); _initialize_exec ();} {extern void _initialize_kernel_u_addr (); _initialize_kernel_u_addr ();} + {extern void _initialize_infptrace (); _initialize_infptrace ();} {extern void _initialize_inftarg (); _initialize_inftarg ();} {extern void _initialize_corelow (); _initialize_corelow ();} -#ifdef KERNEL_DEBUG + {extern void _initialize_core_aout (); _initialize_core_aout ();} {extern void _initialize_kcorelow (); _initialize_kcorelow ();} -#endif {extern void _initialize_remote (); _initialize_remote ();} + {extern void _initialize_dcache (); _initialize_dcache ();} {extern void _initialize_sr_support (); _initialize_sr_support ();} - {extern void _initialize_targets (); _initialize_targets ();} {extern void _initialize_parse (); _initialize_parse ();} {extern void _initialize_language (); _initialize_language ();} {extern void _initialize_buildsym (); _initialize_buildsym ();} + {extern void _initialize_exec (); _initialize_exec ();} {extern void _initialize_maint_cmds (); _initialize_maint_cmds ();} {extern void _initialize_demangler (); _initialize_demangler ();} {extern void _initialize_dbxread (); _initialize_dbxread ();} @@ -43,12 +44,16 @@ void initialize_all_files () { {extern void _initialize_core (); _initialize_core ();} {extern void _initialize_c_language (); _initialize_c_language ();} {extern void _initialize_chill_language (); _initialize_chill_language ();} + {extern void _initialize_f_language (); _initialize_f_language ();} {extern void _initialize_m2_language (); _initialize_m2_language ();} + {extern void _initialize_scheme_language (); _initialize_scheme_language ();} {extern void _initialize_complaints (); _initialize_complaints ();} {extern void _initialize_typeprint (); _initialize_typeprint ();} {extern void _initialize_cp_valprint (); _initialize_cp_valprint ();} + {extern void _initialize_f_valprint (); _initialize_f_valprint ();} + {extern void _initialize_nlmread (); _initialize_nlmread ();} {extern void _initialize_serial (); _initialize_serial ();} {extern void _initialize_mdebugread (); _initialize_mdebugread ();} - {extern void _initialize_utils (); _initialize_utils ();} + {extern void _initialize_annotate (); _initialize_annotate ();} {extern void _initialize_inflow (); _initialize_inflow ();} } diff --git a/gnu/usr.bin/gdb/gdb/kcorelow.c b/gnu/usr.bin/gdb/gdb/kcorelow.c index 104ba29..5aa1f58 100644 --- a/gnu/usr.bin/gdb/gdb/kcorelow.c +++ b/gnu/usr.bin/gdb/gdb/kcorelow.c @@ -31,7 +31,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include #include -#include #include "frame.h" /* required by inferior.h */ #include "inferior.h" #include "symtab.h" @@ -68,8 +67,7 @@ static CORE_ADDR kernel_start; #define kvread(addr, p) \ (target_read_memory((CORE_ADDR)(addr), (char *)(p), sizeof(*(p)))) -int read_pcb (int, CORE_ADDR); -extern struct kinfo_proc* kvm_getprocs (int, int, CORE_ADDR, int*); +extern read_pcb (int, CORE_ADDR); CORE_ADDR ksym_lookup(name) @@ -324,8 +322,6 @@ set_proc_cmd(arg) char *arg; { CORE_ADDR paddr; - struct kinfo_proc *kp; - int cnt = 0; if (!arg) error_no_arg("proc address for new current process"); @@ -333,19 +329,8 @@ set_proc_cmd(arg) error("not debugging kernel"); paddr = (CORE_ADDR)parse_and_eval_address(arg); -fprintf(stderr, "paddr %#x kernel_start %#x ", paddr, kernel_start); - /* assume it's a proc pointer if it's in the kernel */ - if (paddr >= kernel_start) { - if (set_proc_context(paddr)) - error("invalid proc address"); - } else { - kp = kvm_getprocs(core_kd, KERN_PROC_PID, paddr, &cnt); -fprintf(stderr, "cnt %d\n", cnt); - if (!cnt) - error("invalid pid"); - if (set_proc_context((CORE_ADDR)kp->kp_eproc.e_paddr)) - error("invalid proc address"); - } + if (set_proc_context(paddr)) + error("invalid proc address"); } struct target_ops kcore_ops = { diff --git a/gnu/usr.bin/gdb/gdb/kvm-fbsd.c b/gnu/usr.bin/gdb/gdb/kvm-fbsd.c new file mode 100644 index 0000000..9419b6a --- /dev/null +++ b/gnu/usr.bin/gdb/gdb/kvm-fbsd.c @@ -0,0 +1,941 @@ +/* Live and postmortem kernel debugging functions for FreeBSD. + 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 +#include +#include +#include +#include +#include +#include +#include +#include "frame.h" /* required by inferior.h */ +#include "inferior.h" +#include "symtab.h" +#include "command.h" +#include "bfd.h" +#include "target.h" +#include "gdbcore.h" +#include +#include +#include +#include + +#include +#include +#include + +static void kcore_files_info PARAMS ((struct target_ops *)); + +static void kcore_close PARAMS ((int)); + +static void get_kcore_registers PARAMS ((int)); + +static int kcore_xfer_kmem PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *)); + +static int xfer_umem PARAMS ((CORE_ADDR, char *, int, int)); + +static CORE_ADDR ksym_lookup PARAMS ((const char *)); + +static int read_pcb PARAMS ((int, CORE_ADDR)); + +static struct proc * curProc PARAMS ((void)); + +static int set_proc_context PARAMS ((CORE_ADDR paddr)); + +static void kcore_open PARAMS ((char *filename, int from_tty)); + +static void kcore_detach PARAMS ((char *args, int from_tty)); + +static void set_proc_cmd PARAMS ((char *arg, int from_tty)); + +static CORE_ADDR kvtophys PARAMS ((int, CORE_ADDR)); + +static int physrd PARAMS ((int, u_int, char*, int)); + +static int kvm_open PARAMS ((const char *efile, char *cfile, char *sfile, + int perm, char *errout)); + +static int kvm_close PARAMS ((int fd)); + +static int kvm_write PARAMS ((int core_kd, CORE_ADDR memaddr, + char *myaddr, int len)); + +static int kvm_read PARAMS ((int core_kd, CORE_ADDR memaddr, + char *myaddr, int len)); + +static int kvm_uread PARAMS ((int core_kd, struct proc *p, + CORE_ADDR memaddr, char *myaddr, + int len)); + +static int kernel_core_file_hook PARAMS ((int fd, CORE_ADDR addr, + char *buf, int len)); + +static struct kinfo_proc * kvm_getprocs PARAMS ((int cfd, int op, + CORE_ADDR proc, int *cnt)); + +extern struct target_ops kcore_ops; /* Forward decl */ + +/* Non-zero means we are debugging a kernel core file */ +int kernel_debugging = 0; +int kernel_writablecore = 0; + +static char *core_file; +static int core_kd = -1; +static struct proc *cur_proc; +static CORE_ADDR kernel_start; + +/* + * Read the "thing" at kernel address 'addr' into the space pointed to + * by point. The length of the "thing" is determined by the type of p. + * Result is non-zero if transfer fails. + */ +#define kvread(addr, p) \ + (target_read_memory ((CORE_ADDR)(addr), (char *)(p), sizeof(*(p)))) + + + +/* + * The following is FreeBSD-specific hackery to decode special frames + * and elide the assembly-language stub. This could be made faster by + * defining a frame_type field in the machine-dependent frame information, + * but we don't think that's too important right now. + */ +enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall }; + +CORE_ADDR +fbsd_kern_frame_saved_pc (fr) +struct frame_info *fr; +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (fr->frame + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) { + if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) + frametype = tf_trap; + else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) + frametype = tf_interrupt; + else if (strcmp (SYMBOL_NAME(sym), "Xsyscall") == 0) + frametype = tf_syscall; + } + + switch (frametype) { + case tf_normal: + return (this_saved_pc); + +#define oEIP offsetof(struct trapframe, tf_eip) + + case tf_trap: + return (read_memory_integer (fr->frame + 8 + oEIP, 4)); + + case tf_interrupt: + return (read_memory_integer (fr->frame + 16 + oEIP, 4)); + + case tf_syscall: + return (read_memory_integer (fr->frame + 8 + oEIP, 4)); +#undef oEIP + } +} + +CORE_ADDR +fbsd_kern_frame_chain (fr) +struct frame_info *fr; +{ + struct minimal_symbol *sym; + CORE_ADDR this_saved_pc; + enum frametype frametype; + + this_saved_pc = read_memory_integer (fr->frame + 4, 4); + sym = lookup_minimal_symbol_by_pc (this_saved_pc); + frametype = tf_normal; + if (sym != NULL) { + if (strcmp (SYMBOL_NAME(sym), "calltrap") == 0) + frametype = tf_trap; + else if (strncmp (SYMBOL_NAME(sym), "Xresume", 7) == 0) + frametype = tf_interrupt; + else if (strcmp (SYMBOL_NAME(sym), "_Xsyscall") == 0) + frametype = tf_syscall; + } + + switch (frametype) { + case tf_normal: + return (read_memory_integer (fr->frame, 4)); + +#define oEBP offsetof(struct trapframe, tf_ebp) + + case tf_trap: + return (read_memory_integer (fr->frame + 8 + oEBP, 4)); + + case tf_interrupt: + return (read_memory_integer (fr->frame + 16 + oEBP, 4)); + + case tf_syscall: + return (read_memory_integer (fr->frame + 8 + oEBP, 4)); +#undef oEBP + } +} + +static CORE_ADDR +ksym_lookup (name) +const char *name; +{ + struct minimal_symbol *sym; + + sym = lookup_minimal_symbol (name, NULL, NULL); + if (sym == NULL) + error ("kernel symbol `%s' not found.", name); + + return SYMBOL_VALUE_ADDRESS (sym); +} + +static struct proc * +curProc () +{ + struct proc *p; + CORE_ADDR addr = ksym_lookup ("curproc"); + + if (kvread (addr, &p)) + error ("cannot read proc pointer at %x\n", addr); + return p; +} + +/* + * Set the process context to that of the proc structure at + * system address paddr. + */ +static int +set_proc_context (paddr) + CORE_ADDR paddr; +{ + struct proc p; + + if (paddr < kernel_start) + return (1); + + cur_proc = (struct proc *)paddr; +#ifdef notyet + set_kernel_boundaries (cur_proc); +#endif + + /* Fetch all registers from core file */ + target_fetch_registers (-1); + + /* Now, set up the frame cache, and print the top of stack */ + flush_cached_frames (); + set_current_frame (create_new_frame (read_fp (), read_pc ())); + select_frame (get_current_frame (), 0); + return (0); +} + +/* Discard all vestiges of any previous core file + and mark data and stack spaces as empty. */ + +/* ARGSUSED */ +static void +kcore_close (quitting) + int quitting; +{ + inferior_pid = 0; /* Avoid confusion from thread stuff */ + + if (core_kd) + { + kvm_close (core_kd); + free (core_file); + core_file = NULL; + core_kd = -1; + } +} + +/* This routine opens and sets up the core file bfd */ + +static void +kcore_open (filename, from_tty) + char *filename; + int from_tty; +{ + const char *p; + struct cleanup *old_chain; + char buf[256], *cp; + int ontop; + CORE_ADDR addr; + struct pcb pcb; + + target_preopen (from_tty); + + unpush_target (&kcore_ops); + + if (!filename) + { + /*error (core_kd?*/ + error ( (core_kd >= 0)? + "No core file specified. (Use `detach' to stop debugging a core file.)" + : "No core file specified."); + } + + filename = tilde_expand (filename); + if (filename[0] != '/') + { + cp = concat (current_directory, "/", filename, NULL); + free (filename); + filename = cp; + } + + old_chain = make_cleanup (free, filename); + + /* + * gdb doesn't really do anything if the exec-file couldn't + * be opened (in that case exec_bfd is NULL). Usually that's + * no big deal, but kvm_open needs the exec-file's name, + * which results in dereferencing a NULL pointer, a real NO-NO ! + * So, check here if the open of the exec-file succeeded. + */ + if (exec_bfd == NULL) /* the open failed */ + error ("kgdb could not open the exec-file, please check the name you used !"); + + core_kd = kvm_open (exec_bfd->filename, filename, NULL, + kernel_writablecore? O_RDWR : O_RDONLY, "kgdb: "); + if (core_kd < 0) + perror_with_name (filename); + + /* Looks semi-reasonable. Toss the old core file and work on the new. */ + + discard_cleanups (old_chain); /* Don't free filename any more */ + core_file = filename; + ontop = !push_target (&kcore_ops); + + kernel_start = bfd_get_start_address (exec_bfd); /* XXX */ + + /* print out the panic string if there is one */ + if (kvread (ksym_lookup ("panicstr"), &addr) == 0 + && addr != 0 + && target_read_memory (addr, buf, sizeof (buf)) == 0) + { + for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++) + if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp))) + *cp = '?'; + *cp = '\0'; + if (buf[0] != '\0') + printf ("panic: %s\n", buf); + } + + if (!ontop) + { + warning ("you won't be able to access this core file until you terminate\n\ +your %s; do ``info files''", target_longname); + return; + } + + /* we may need this later */ + cur_proc = (struct proc *)curProc (); + /* Now, set up the frame cache, and print the top of stack */ + flush_cached_frames (); + set_current_frame (create_new_frame (read_fp (), read_pc ())); + select_frame (get_current_frame (), 0); + print_stack_frame (selected_frame, selected_frame_level, 1); +} + +static void +kcore_detach (args, from_tty) + char *args; + int from_tty; +{ + if (args) + error ("Too many arguments"); + unpush_target (&kcore_ops); + reinit_frame_cache (); + if (from_tty) + printf_filtered ("No kernel core file now.\n"); +} + +/* Get the registers out of a core file. This is the machine- + independent part. Fetch_core_registers is the machine-dependent + part, typically implemented in the xm-file for each architecture. */ + +/* We just get all the registers, so we don't use regno. */ +/* ARGSUSED */ +static void +get_kcore_registers (regno) + int regno; +{ + struct user *uaddr; + + /* find the pcb for the current process */ + if (kvread (&cur_proc->p_addr, &uaddr)) + error ("cannot read u area ptr for proc at %#x", cur_proc); + if (read_pcb (core_kd, (CORE_ADDR)&uaddr->u_pcb) < 0) + error ("cannot read pcb at %#x", &uaddr->u_pcb); +} + +static void +kcore_files_info (t) + struct target_ops *t; +{ + printf ("\t`%s'\n", core_file); +} + +static int +kcore_xfer_kmem (memaddr, myaddr, len, write, target) + CORE_ADDR memaddr; + char *myaddr; + int len; + int write; + struct target_ops *target; +{ + int n; + + if (!memaddr) + return (0); + + if (memaddr < kernel_start) + return xfer_umem (memaddr, myaddr, len, write); + + n = write ? + kvm_write (core_kd, memaddr, myaddr, len) : + kvm_read (core_kd, memaddr, myaddr, len) ; + + if (n < 0) + return 0; + return n; +} + +static int +xfer_umem (memaddr, myaddr, len, write) + CORE_ADDR memaddr; + char *myaddr; + int len; + int write; /* ignored */ +{ + int n; + struct proc proc; + + if (kvread (cur_proc, &proc)) + error ("cannot read proc at %#x", cur_proc); + n = kvm_uread (core_kd, &proc, memaddr, myaddr, len) ; + + if (n < 0) + return 0; + return n; +} + +static void +set_proc_cmd (arg, from_tty) + char *arg; + int from_tty; +{ + CORE_ADDR paddr; + struct kinfo_proc *kp; + int cnt = 0; + + if (!arg) + error_no_arg ("proc address for new current process"); + if (!kernel_debugging) + error ("not debugging kernel"); + + paddr = (CORE_ADDR)parse_and_eval_address (arg); + /* assume it's a proc pointer if it's in the kernel */ + if (paddr >= kernel_start) { + if (set_proc_context(paddr)) + error("invalid proc address"); + } else { + kp = kvm_getprocs(core_kd, KERN_PROC_PID, paddr, &cnt); + if (!cnt) + error("invalid pid"); + if (set_proc_context((CORE_ADDR)kp->kp_eproc.e_paddr)) + error("invalid proc address"); + } +} + + + +#define KERNOFF ((unsigned)KERNBASE) +#define INKERNEL(x) ((x) >= KERNOFF) + +static CORE_ADDR sbr; +static CORE_ADDR curpcb; +static CORE_ADDR kstack; +static int found_pcb; +static int devmem; +static int kfd; +static struct pcb pcb; + +/* substitutes for the stuff in libkvm which doesn't work */ +/* most of this was taken from the old kgdb */ + +/* we don't need all this stuff, but the call should look the same */ + +static int +kvm_open (efile, cfile, sfile, perm, errout) + const char *efile; + char *cfile; + char *sfile; /* makes this kvm_open more compatible to the one in libkvm */ + int perm; + char *errout; /* makes this kvm_open more compatible to the one in libkvm */ +{ + struct stat stb; + CORE_ADDR addr; + int cfd; + + if ((cfd = open (cfile, perm, 0)) < 0) + return (cfd); + + fstat (cfd, &stb); + if ((stb.st_mode & S_IFMT) == S_IFCHR + && stb.st_rdev == makedev (2, 0)) + { + devmem = 1; + kfd = open ("/dev/kmem", perm, 0); + } + + physrd (cfd, ksym_lookup ("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr); + printf ("IdlePTD %x\n", sbr); + curpcb = ksym_lookup ("curpcb") - KERNOFF; + physrd (cfd, curpcb, (char*)&curpcb, sizeof curpcb); + kstack = ksym_lookup ("kstack"); + + found_pcb = 1; /* for vtophys */ + if (!devmem) + read_pcb (cfd, ksym_lookup ("dumppcb") - KERNOFF); + else + read_pcb (cfd, kvtophys (cfd, kstack)); + + return (cfd); +} + +static int +kvm_close (fd) + int fd; +{ + return (close (fd)); +} + +static int +kvm_write (core_kd, memaddr, myaddr, len) + int core_kd; + CORE_ADDR memaddr; + char *myaddr; +{ + int cc; + + if (devmem) + { + if (kfd > 0) + { + /* + * Just like kvm_read, only we write. + */ + errno = 0; + if (lseek (kfd, (off_t)memaddr, 0) < 0 + && errno != 0) + { + error ("kvm_write:invalid address (%x)", memaddr); + return (0); + } + cc = write (kfd, myaddr, len); + if (cc < 0) + { + error ("kvm_write:write failed"); + return (0); + } + else if (cc < len) + error ("kvm_write:short write"); + return (cc); + } + else + return (0); + } + else + { + printf ("kvm_write not implemented for dead kernels\n"); + return (0); + } + /* NOTREACHED */ +} + +static int +kvm_read (core_kd, memaddr, myaddr, len) + int core_kd; + CORE_ADDR memaddr; + char *myaddr; +{ + return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); +} + +static int +kvm_uread (core_kd, p, memaddr, myaddr, len) + int core_kd; + register struct proc *p; + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + register char *cp; + char procfile[MAXPATHLEN]; + ssize_t amount; + int fd; + + if (devmem) + { + cp = myaddr; + + sprintf (procfile, "/proc/%d/mem", p->p_pid); + fd = open (procfile, O_RDONLY, 0); + + if (fd < 0) + { + error ("cannot open %s", procfile); + close (fd); + return (0); + } + + while (len > 0) + { + if (lseek (fd, memaddr, 0) == -1 && errno != 0) + { + error ("invalid address (%x) in %s", + memaddr, procfile); + break; + } + amount = read (fd, cp, len); + if (amount < 0) + { + error ("error reading %s", procfile); + break; + } + cp += amount; + memaddr += amount; + len -= amount; + } + + close (fd); + return (ssize_t) (cp - myaddr); + } + else + return (kernel_core_file_hook (core_kd, memaddr, myaddr, len)); +} + +static struct kinfo_proc kp; + +/* + * try to do what kvm_proclist in libkvm would do + */ +static int +kvm_proclist (cfd, pid, p, cnt) +int cfd, pid, *cnt; +struct proc *p; +{ + struct proc lp; + + for (; p != NULL; p = lp.p_list.le_next) { + if (!kvm_read(cfd, (CORE_ADDR)p, (char *)&lp, sizeof (lp))) + return (0); + if (lp.p_pid != pid) + continue; + kp.kp_eproc.e_paddr = p; + *cnt = 1; + return (1); + } + *cnt = 0; + return (0); +} + +/* + * try to do what kvm_deadprocs in libkvm would do + */ +static struct kinfo_proc * +kvm_deadprocs (cfd, pid, cnt) +int cfd, pid, *cnt; +{ + CORE_ADDR allproc, zombproc; + struct proc *p; + + allproc = ksym_lookup("allproc"); + if (kvm_read(cfd, allproc, (char *)&p, sizeof (p)) == 0) + return (NULL); + kvm_proclist (cfd, pid, p, cnt); + if (!*cnt) { + zombproc = ksym_lookup("zombproc"); + if (kvm_read(cfd, zombproc, (char *)&p, sizeof (p)) == 0) + return (NULL); + kvm_proclist (cfd, pid, p, cnt); + } + return (&kp); +} + +/* + * try to do what kvm_getprocs in libkvm would do + */ +static struct kinfo_proc * +kvm_getprocs (cfd, op, proc, cnt) +int cfd, op, *cnt; +CORE_ADDR proc; +{ + int mib[4], size; + + *cnt = 0; + /* assume it's a pid */ + if (devmem) { /* "live" kernel, use sysctl */ + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = (int)proc; + size = sizeof (kp); + if (sysctl (mib, 4, &kp, &size, NULL, 0) < 0) { + perror("sysctl"); + *cnt = 0; + return (NULL); + } + if (!size) + *cnt = 0; + else + *cnt = 1; + return (&kp); + } else + return (kvm_deadprocs (cfd, (int)proc, cnt)); +} + +static int +physrd (cfd, addr, dat, len) + int cfd; + u_int addr; + char *dat; + int len; +{ + if (lseek (cfd, (off_t)addr, L_SET) == -1) + return (-1); + return (read (cfd, dat, len)); +} + +static CORE_ADDR +kvtophys (fd, addr) + int fd; + CORE_ADDR addr; +{ + CORE_ADDR v; + unsigned int pte; + static CORE_ADDR PTD = -1; + CORE_ADDR current_ptd; + + /* + * If we're looking at the kernel stack, + * munge the address to refer to the user space mapping instead; + * that way we get the requested process's kstack, not the running one. + */ + /* + * this breaks xlating user addresses from a crash dump so only + * do it for a "live" kernel. + */ + if (devmem && addr >= kstack && addr < kstack + ctob (UPAGES)) + addr = (addr - kstack) + curpcb; + + /* + * We may no longer have a linear system page table... + * + * Here's the scoop. IdlePTD contains the physical address + * of a page table directory that always maps the kernel. + * IdlePTD is in memory that is mapped 1-to-1, so we can + * find it easily given its 'virtual' address from ksym_lookup(). + * For hysterical reasons, the value of IdlePTD is stored in sbr. + * + * To look up a kernel address, we first convert it to a 1st-level + * address and look it up in IdlePTD. This gives us the physical + * address of a page table page; we extract the 2nd-level part of + * VA and read the 2nd-level pte. Finally, we add the offset part + * of the VA into the physical address from the pte and return it. + * + * User addresses are a little more complicated. If we don't have + * a current PCB from read_pcb(), we use PTD, which is the (fixed) + * virtual address of the current ptd. Since it's NOT in 1-to-1 + * kernel space, we must look it up using IdlePTD. If we do have + * a pcb, we get the ptd from pcb_ptd. + */ + + if (INKERNEL (addr)) + current_ptd = sbr; + else if (found_pcb == 0) + { + if (PTD == -1) + PTD = kvtophys (fd, ksym_lookup ("PTD")); + current_ptd = PTD; + } + else + current_ptd = pcb.pcb_cr3; + + /* + * Read the first-level page table (ptd). + */ + v = current_ptd + ( (unsigned)addr >> PDRSHIFT) * sizeof pte; + if (physrd (fd, v, (char *)&pte, sizeof pte) < 0 || (pte&PG_V) == 0) + return (~0); + + /* + * Read the second-level page table. + */ + v = (pte&PG_FRAME) + ((addr >> PAGE_SHIFT)&(NPTEPG-1)) * sizeof pte; + if (physrd (fd, v, (char *) &pte, sizeof (pte)) < 0 || (pte&PG_V) == 0) + return (~0); + + addr = (pte & PG_FRAME) + (addr & PAGE_MASK); +#if 0 + printf ("vtophys (%x) -> %x\n", oldaddr, addr); +#endif + return (addr); +} + +static int +read_pcb (fd, uaddr) + int fd; + CORE_ADDR uaddr; +{ + int i; + int *pcb_regs = (int *)&pcb; + int eip; + CORE_ADDR nuaddr = uaddr; + + /* need this for the `proc' command to work */ + if (INKERNEL(uaddr)) + nuaddr = kvtophys(fd, uaddr); + + if (physrd (fd, nuaddr, (char *)&pcb, sizeof pcb) < 0) + { + error ("cannot read pcb at %x\n", uaddr); + return (-1); + } + printf ("current pcb at %x\n", uaddr); + + /* + * get the register values out of the sys pcb and + * store them where `read_register' will find them. + */ + for (i = 0; i < 8; ++i) + supply_register (i, (char *)&pcb_regs[i+10]); + supply_register (8, (char *)&pcb_regs[8]); /* eip */ + supply_register (9, (char *)&pcb_regs[9]); /* eflags */ + for (i = 10; i < 13; ++i) /* cs, ss, ds */ + supply_register (i, (char *)&pcb_regs[i+9]); + supply_register (13, (char *)&pcb_regs[18]); /* es */ + for (i = 14; i < 16; ++i) /* fs, gs */ + supply_register (i, (char *)&pcb_regs[i+8]); + +#if 0 /* doesn't work ??? */ + /* Hmm... */ + if (target_read_memory (pcb_regs[5+10]+4, &eip, sizeof eip, 0)) + error ("Cannot read PC."); + supply_register (8, (char *)&eip); /* eip */ +#endif + + /* XXX 80387 registers? */ +} + +/* + * read len bytes from kernel virtual address 'addr' into local + * buffer 'buf'. Return numbert of bytes if read ok, 0 otherwise. On read + * errors, portion of buffer not read is zeroed. + */ + +static int +kernel_core_file_hook (fd, addr, buf, len) + int fd; + CORE_ADDR addr; + char *buf; + int len; +{ + int i; + CORE_ADDR paddr; + register char *cp; + int cc; + + cp = buf; + + while (len > 0) + { + paddr = kvtophys (fd, addr); + if (paddr == ~0) + { + memset (buf, '\000', len); + break; + } + /* we can't read across a page boundary */ + i = min (len, PAGE_SIZE - (addr & PAGE_MASK)); + if ( (cc = physrd (fd, paddr, cp, i)) <= 0) + { + memset (cp, '\000', len); + return (cp - buf); + } + cp += cc; + addr += cc; + len -= cc; + } + return (cp - buf); +} + +struct target_ops kcore_ops = { + "kcore", /* to_shortname */ + "Kernel core dump file", /* to_longname */ + "Use a core file as a target. Specify the filename of the core file.", /* to_doc */ + kcore_open, /* to_open */ + kcore_close, /* to_close */ + find_default_attach, /* to_attach */ + kcore_detach, /* to_detach */ + NULL, /* to_resume */ + NULL, /* to_wait */ + get_kcore_registers, /* to_fetch_registers */ + NULL, /* to_store_registers */ + NULL, /* to_prepare_to_store */ + kcore_xfer_kmem, /* to_xfer_memory */ + kcore_files_info, /* 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 */ + NULL, /* to_kill */ + NULL, /* to_load */ + NULL, /* to_lookup_symbol */ + find_default_create_inferior, /* to_create_inferior */ + NULL, /* to_mourn_inferior */ + 0, /* to_can_run */ + 0, /* to_notice_signals */ + NULL, /* to_thread_alive */ + 0, /* to_stop */ + kcore_stratum, /* to_stratum */ + NULL, /* to_next */ + 0, /* 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 */ +}; + +void +_initialize_kcorelow() +{ + add_target (&kcore_ops); + add_com ("proc", class_obscure, set_proc_cmd, "Set current process context"); +} diff --git a/gnu/usr.bin/gdb/gdb/language.c b/gnu/usr.bin/gdb/gdb/language.c deleted file mode 100644 index 6d254fb..0000000 --- a/gnu/usr.bin/gdb/gdb/language.c +++ /dev/null @@ -1,1311 +0,0 @@ -/* Multiple source language support for GDB. - Copyright 1991, 1992 Free Software Foundation, Inc. - Contributed by the Department of Computer Science at the State University - of New York at Buffalo. - -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. */ - -/* This file contains functions that return things that are specific - to languages. Each function should examine current_language if necessary, - and return the appropriate result. */ - -/* FIXME: Most of these would be better organized as macros which - return data out of a "language-specific" struct pointer that is set - whenever the working language changes. That would be a lot faster. */ - -#include "defs.h" -#include -#include - -#include "symtab.h" -#include "gdbtypes.h" -#include "value.h" -#include "gdbcmd.h" -#include "frame.h" -#include "expression.h" -#include "language.h" -#include "target.h" -#include "parser-defs.h" - -static void -show_language_command PARAMS ((char *, int)); - -static void -set_language_command PARAMS ((char *, int)); - -static void -show_type_command PARAMS ((char *, int)); - -static void -set_type_command PARAMS ((char *, int)); - -static void -show_range_command PARAMS ((char *, int)); - -static void -set_range_command PARAMS ((char *, int)); - -static void -set_range_str PARAMS ((void)); - -static void -set_type_str PARAMS ((void)); - -static void -set_lang_str PARAMS ((void)); - -static void -unk_lang_error PARAMS ((char *)); - -static int -unk_lang_parser PARAMS ((void)); - -static void -show_check PARAMS ((char *, int)); - -static void -set_check PARAMS ((char *, int)); - -static void -set_type_range PARAMS ((void)); - -/* Forward declaration */ -extern const struct language_defn unknown_language_defn; -extern char *warning_pre_print; - -/* The current (default at startup) state of type and range checking. - (If the modes are set to "auto", though, these are changed based - on the default language at startup, and then again based on the - language of the first source file. */ - -enum range_mode range_mode = range_mode_auto; -enum range_check range_check = range_check_off; -enum type_mode type_mode = type_mode_auto; -enum type_check type_check = type_check_off; - -/* The current language and language_mode (see language.h) */ - -const struct language_defn *current_language = &unknown_language_defn; -enum language_mode language_mode = language_mode_auto; - -/* The language that the user expects to be typing in (the language - of main(), or the last language we notified them about, or C). */ - -const struct language_defn *expected_language; - -/* The list of supported languages. The list itself is malloc'd. */ - -static const struct language_defn **languages; -static unsigned languages_size; -static unsigned languages_allocsize; -#define DEFAULT_ALLOCSIZE 4 - -/* The "set language/type/range" commands all put stuff in these - buffers. This is to make them work as set/show commands. The - user's string is copied here, then the set_* commands look at - them and update them to something that looks nice when it is - printed out. */ - -static char *language; -static char *type; -static char *range; - -/* Warning issued when current_language and the language of the current - frame do not match. */ -char lang_frame_mismatch_warn[] = - "Warning: the current language does not match this frame."; - - -/* This page contains the functions corresponding to GDB commands - and their helpers. */ - -/* Show command. Display a warning if the language set - does not match the frame. */ -static void -show_language_command (ignore, from_tty) - char *ignore; - int from_tty; -{ - enum language flang; /* The language of the current frame */ - - 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); -} - -/* Set command. Change the current working language. */ -static void -set_language_command (ignore, from_tty) - char *ignore; - int from_tty; -{ - int i; - enum language flang; - char *err_lang; - - /* FIXME -- do this from the list, with HELP. */ - if (!language || !language[0]) { - printf_unfiltered("The currently understood settings are:\n\n"); - printf_unfiltered ("local or auto Automatic setting based on source file\n"); - printf_unfiltered ("c Use the C language\n"); - printf_unfiltered ("c++ Use the C++ language\n"); - printf_unfiltered ("chill Use the Chill language\n"); - printf_unfiltered ("modula-2 Use the Modula-2 language\n"); - /* Restore the silly string. */ - set_language(current_language->la_language); - return; - } - - /* Search the list of languages for a match. */ - for (i = 0; i < languages_size; i++) { - if (STREQ (languages[i]->la_name, language)) { - /* Found it! Go into manual mode, and use this language. */ - if (languages[i]->la_language == language_auto) { - /* Enter auto mode. Set to the current frame's language, if known. */ - language_mode = language_mode_auto; - flang = get_frame_language(); - if (flang!=language_unknown) - set_language(flang); - expected_language = current_language; - return; - } else { - /* Enter manual mode. Set the specified language. */ - language_mode = language_mode_manual; - current_language = languages[i]; - set_type_range (); - set_lang_str(); - expected_language = current_language; - return; - } - } - } - - /* Reset the language (esp. the global string "language") to the - correct values. */ - err_lang=savestring(language,strlen(language)); - make_cleanup (free, err_lang); /* Free it after error */ - set_language(current_language->la_language); - error ("Unknown language `%s'.",err_lang); -} - -/* Show command. Display a warning if the type setting does - not match the current language. */ -static void -show_type_command(ignore, from_tty) - char *ignore; - int from_tty; -{ - if (type_check != current_language->la_type_check) - printf_unfiltered( -"Warning: the current type check setting does not match the language.\n"); -} - -/* Set command. Change the setting for type checking. */ -static void -set_type_command(ignore, from_tty) - char *ignore; - int from_tty; -{ - if (STREQ(type,"on")) - { - type_check = type_check_on; - type_mode = type_mode_manual; - } - else if (STREQ(type,"warn")) - { - type_check = type_check_warn; - type_mode = type_mode_manual; - } - else if (STREQ(type,"off")) - { - type_check = type_check_off; - type_mode = type_mode_manual; - } - else if (STREQ(type,"auto")) - { - type_mode = type_mode_auto; - set_type_range(); - /* Avoid hitting the set_type_str call below. We - did it in set_type_range. */ - return; - } - set_type_str(); - show_type_command((char *)NULL, from_tty); -} - -/* Show command. Display a warning if the range setting does - not match the current language. */ -static void -show_range_command(ignore, from_tty) - char *ignore; - int from_tty; -{ - - if (range_check != current_language->la_range_check) - printf_unfiltered( -"Warning: the current range check setting does not match the language.\n"); -} - -/* Set command. Change the setting for range checking. */ -static void -set_range_command(ignore, from_tty) - char *ignore; - int from_tty; -{ - if (STREQ(range,"on")) - { - range_check = range_check_on; - range_mode = range_mode_manual; - } - else if (STREQ(range,"warn")) - { - range_check = range_check_warn; - range_mode = range_mode_manual; - } - else if (STREQ(range,"off")) - { - range_check = range_check_off; - range_mode = range_mode_manual; - } - else if (STREQ(range,"auto")) - { - range_mode = range_mode_auto; - set_type_range(); - /* Avoid hitting the set_range_str call below. We - did it in set_type_range. */ - return; - } - set_range_str(); - show_range_command((char *)0, from_tty); -} - -/* Set the status of range and type checking based on - the current modes and the current language. - If SHOW is non-zero, then print out the current language, - type and range checking status. */ -static void -set_type_range() -{ - - if (range_mode == range_mode_auto) - range_check = current_language->la_range_check; - - if (type_mode == type_mode_auto) - type_check = current_language->la_type_check; - - set_type_str(); - set_range_str(); -} - -/* Set current language to (enum language) LANG. */ - -void -set_language(lang) - enum language lang; -{ - int i; - - for (i = 0; i < languages_size; i++) { - if (languages[i]->la_language == lang) { - current_language = languages[i]; - set_type_range (); - set_lang_str(); - break; - } - } -} - -/* This page contains functions that update the global vars - language, type and range. */ -static void -set_lang_str() -{ - char *prefix = ""; - - free (language); - if (language_mode == language_mode_auto) - prefix = "auto; currently "; - - language = concat(prefix, current_language->la_name, NULL); -} - -static void -set_type_str() -{ - char *tmp, *prefix = ""; - - free (type); - if (type_mode==type_mode_auto) - prefix = "auto; currently "; - - switch(type_check) - { - case type_check_on: - tmp = "on"; - break; - case type_check_off: - tmp = "off"; - break; - case type_check_warn: - tmp = "warn"; - break; - default: - error ("Unrecognized type check setting."); - } - - type = concat(prefix,tmp,NULL); -} - -static void -set_range_str() -{ - char *tmp, *pref = ""; - - free (range); - if (range_mode==range_mode_auto) - pref = "auto; currently "; - - switch(range_check) - { - case range_check_on: - tmp = "on"; - break; - case range_check_off: - tmp = "off"; - break; - case range_check_warn: - tmp = "warn"; - break; - default: - error ("Unrecognized range check setting."); - } - - range = concat(pref,tmp,NULL); -} - - -/* Print out the current language settings: language, range and - type checking. If QUIETLY, print only what has changed. */ - -void -language_info (quietly) - int quietly; -{ - if (quietly && expected_language == current_language) - return; - - expected_language = current_language; - printf_unfiltered("Current language: %s\n",language); - show_language_command((char *)0, 1); - - if (!quietly) - { - printf_unfiltered("Type checking: %s\n",type); - show_type_command((char *)0, 1); - printf_unfiltered("Range checking: %s\n",range); - show_range_command((char *)0, 1); - } -} - -/* Return the result of a binary operation. */ - -#if 0 /* Currently unused */ - -struct type * -binop_result_type (v1, v2) - value_ptr v1, v2; -{ - int l1,l2,size,uns; - - l1 = TYPE_LENGTH(VALUE_TYPE(v1)); - l2 = TYPE_LENGTH(VALUE_TYPE(v2)); - - switch(current_language->la_language) - { - case language_c: - case language_cplus: - if (TYPE_CODE(VALUE_TYPE(v1))==TYPE_CODE_FLT) - return TYPE_CODE(VALUE_TYPE(v2)) == TYPE_CODE_FLT && l2 > l1 ? - VALUE_TYPE(v2) : VALUE_TYPE(v1); - else if (TYPE_CODE(VALUE_TYPE(v2))==TYPE_CODE_FLT) - return TYPE_CODE(VALUE_TYPE(v1)) == TYPE_CODE_FLT && l1 > l2 ? - VALUE_TYPE(v1) : VALUE_TYPE(v2); - else if (TYPE_UNSIGNED(VALUE_TYPE(v1)) && l1 > l2) - return VALUE_TYPE(v1); - else if (TYPE_UNSIGNED(VALUE_TYPE(v2)) && l2 > l1) - return VALUE_TYPE(v2); - else /* Both are signed. Result is the longer type */ - return l1 > l2 ? VALUE_TYPE(v1) : VALUE_TYPE(v2); - break; - case language_m2: - /* If we are doing type-checking, l1 should equal l2, so this is - not needed. */ - return l1 > l2 ? VALUE_TYPE(v1) : VALUE_TYPE(v2); - break; - case language_chill: - error ("Missing Chill support in function binop_result_check.");/*FIXME*/ - } - abort(); - return (struct type *)0; /* For lint */ -} - -#endif /* 0 */ - - -/* This page contains functions that return format strings for - printf for printing out numbers in different formats */ - -/* Returns the appropriate printf format for hexadecimal - numbers. */ -char * -local_hex_format_custom(pre) - char *pre; -{ - static char form[50]; - - strcpy (form, local_hex_format_prefix ()); - strcat (form, "%"); - strcat (form, pre); - strcat (form, local_hex_format_specifier ()); - strcat (form, local_hex_format_suffix ()); - return form; -} - -/* Converts a number to hexadecimal and stores it in a static - string. Returns a pointer to this string. */ -char * -local_hex_string (num) - unsigned long num; -{ - static char res[50]; - - sprintf (res, local_hex_format(), num); - return res; -} - -/* Converts a number to custom hexadecimal and stores it in a static - string. Returns a pointer to this string. */ -char * -local_hex_string_custom(num,pre) - unsigned long num; - char *pre; -{ - static char res[50]; - - sprintf (res, local_hex_format_custom(pre), num); - return res; -} - -/* Returns the appropriate printf format for octal - numbers. */ -char * -local_octal_format_custom(pre) - char *pre; -{ - static char form[50]; - - strcpy (form, local_octal_format_prefix ()); - strcat (form, "%"); - strcat (form, pre); - strcat (form, local_octal_format_specifier ()); - strcat (form, local_octal_format_suffix ()); - return form; -} - -/* Returns the appropriate printf format for decimal numbers. */ -char * -local_decimal_format_custom(pre) - char *pre; -{ - static char form[50]; - - strcpy (form, local_decimal_format_prefix ()); - strcat (form, "%"); - strcat (form, pre); - strcat (form, local_decimal_format_specifier ()); - strcat (form, local_decimal_format_suffix ()); - return form; -} - -/* This page contains functions that are used in type/range checking. - They all return zero if the type/range check fails. - - It is hoped that these will make extending GDB to parse different - languages a little easier. These are primarily used in eval.c when - evaluating expressions and making sure that their types are correct. - Instead of having a mess of conjucted/disjuncted expressions in an "if", - the ideas of type can be wrapped up in the following functions. - - Note that some of them are not currently dependent upon which language - is currently being parsed. For example, floats are the same in - C and Modula-2 (ie. the only floating point type has TYPE_CODE of - TYPE_CODE_FLT), while booleans are different. */ - -/* Returns non-zero if its argument is a simple type. This is the same for - both Modula-2 and for C. In the C case, TYPE_CODE_CHAR will never occur, - and thus will never cause the failure of the test. */ -int -simple_type(type) - struct type *type; -{ - switch (TYPE_CODE (type)) { - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_ENUM: - case TYPE_CODE_FLT: - case TYPE_CODE_RANGE: - case TYPE_CODE_BOOL: - return 1; - - default: - return 0; - } -} - -/* Returns non-zero if its argument is of an ordered type. - An ordered type is one in which the elements can be tested for the - properties of "greater than", "less than", etc, or for which the - operations "increment" or "decrement" make sense. */ -int -ordered_type (type) - struct type *type; -{ - switch (TYPE_CODE (type)) { - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_ENUM: - case TYPE_CODE_FLT: - case TYPE_CODE_RANGE: - return 1; - - default: - return 0; - } -} - -/* Returns non-zero if the two types are the same */ -int -same_type (arg1, arg2) - struct type *arg1, *arg2; -{ - if (structured_type(arg1) ? !structured_type(arg2) : structured_type(arg2)) - /* One is structured and one isn't */ - return 0; - else if (structured_type(arg1) && structured_type(arg2)) - return arg1 == arg2; - else if (numeric_type(arg1) && numeric_type(arg2)) - return (TYPE_CODE(arg2) == TYPE_CODE(arg1)) && - (TYPE_UNSIGNED(arg1) == TYPE_UNSIGNED(arg2)) - ? 1 : 0; - else - return arg1==arg2; -} - -/* Returns non-zero if the type is integral */ -int -integral_type (type) - struct type *type; -{ - switch(current_language->la_language) - { - case language_c: - case language_cplus: - return (TYPE_CODE(type) != TYPE_CODE_INT) && - (TYPE_CODE(type) != TYPE_CODE_ENUM) ? 0 : 1; - case language_m2: - return TYPE_CODE(type) != TYPE_CODE_INT ? 0 : 1; - case language_chill: - error ("Missing Chill support in function integral_type."); /*FIXME*/ - default: - error ("Language not supported."); - } -} - -/* Returns non-zero if the value is numeric */ -int -numeric_type (type) - struct type *type; -{ - switch (TYPE_CODE (type)) { - case TYPE_CODE_INT: - case TYPE_CODE_FLT: - return 1; - - default: - return 0; - } -} - -/* Returns non-zero if the value is a character type */ -int -character_type (type) - struct type *type; -{ - switch(current_language->la_language) - { - case language_chill: - case language_m2: - return TYPE_CODE(type) != TYPE_CODE_CHAR ? 0 : 1; - - case language_c: - case language_cplus: - return (TYPE_CODE(type) == TYPE_CODE_INT) && - TYPE_LENGTH(type) == sizeof(char) - ? 1 : 0; - default: - return (0); - } -} - -/* Returns non-zero if the value is a string type */ -int -string_type (type) - struct type *type; -{ - switch(current_language->la_language) - { - case language_chill: - case language_m2: - return TYPE_CODE(type) != TYPE_CODE_STRING ? 0 : 1; - - case language_c: - case language_cplus: - /* C does not have distinct string type. */ - return (0); - default: - return (0); - } -} - -/* Returns non-zero if the value is a boolean type */ -int -boolean_type (type) - struct type *type; -{ - if (TYPE_CODE (type) == TYPE_CODE_BOOL) - return 1; - switch(current_language->la_language) - { - case language_c: - case language_cplus: - /* Might be more cleanly handled by having a TYPE_CODE_INT_NOT_BOOL - for CHILL and such languages, or a TYPE_CODE_INT_OR_BOOL for C. */ - if (TYPE_CODE (type) == TYPE_CODE_INT) - return 1; - default: - break; - } - return 0; -} - -/* Returns non-zero if the value is a floating-point type */ -int -float_type (type) - struct type *type; -{ - return TYPE_CODE(type) == TYPE_CODE_FLT; -} - -/* Returns non-zero if the value is a pointer type */ -int -pointer_type(type) - struct type *type; -{ - return TYPE_CODE(type) == TYPE_CODE_PTR || - TYPE_CODE(type) == TYPE_CODE_REF; -} - -/* Returns non-zero if the value is a structured type */ -int -structured_type(type) - struct type *type; -{ - switch(current_language->la_language) - { - case language_c: - case language_cplus: - return (TYPE_CODE(type) == TYPE_CODE_STRUCT) || - (TYPE_CODE(type) == TYPE_CODE_UNION) || - (TYPE_CODE(type) == TYPE_CODE_ARRAY); - case language_m2: - return (TYPE_CODE(type) == TYPE_CODE_STRUCT) || - (TYPE_CODE(type) == TYPE_CODE_SET) || - (TYPE_CODE(type) == TYPE_CODE_ARRAY); - case language_chill: - error ("Missing Chill support in function structured_type."); /*FIXME*/ - default: - return (0); - } -} - -/* This page contains functions that return info about - (struct value) values used in GDB. */ - -/* Returns non-zero if the value VAL represents a true value. */ -int -value_true (val) - value_ptr val; -{ - /* It is possible that we should have some sort of error if a non-boolean - value is used in this context. Possibly dependent on some kind of - "boolean-checking" option like range checking. But it should probably - not depend on the language except insofar as is necessary to identify - a "boolean" value (i.e. in C using a float, pointer, etc., as a boolean - should be an error, probably). */ - return !value_logical_not (val); -} - -/* Returns non-zero if the operator OP is defined on - the values ARG1 and ARG2. */ - -#if 0 /* Currently unused */ - -void -binop_type_check(arg1,arg2,op) - value_ptr arg1,arg2; - int op; -{ - struct type *t1, *t2; - - /* If we're not checking types, always return success. */ - if (!STRICT_TYPE) - return; - - t1=VALUE_TYPE(arg1); - if (arg2 != NULL) - t2=VALUE_TYPE(arg2); - else - t2=NULL; - - switch(op) - { - case BINOP_ADD: - case BINOP_SUB: - if ((numeric_type(t1) && pointer_type(t2)) || - (pointer_type(t1) && numeric_type(t2))) - { - warning ("combining pointer and integer.\n"); - break; - } - case BINOP_MUL: - case BINOP_LSH: - case BINOP_RSH: - if (!numeric_type(t1) || !numeric_type(t2)) - type_op_error ("Arguments to %s must be numbers.",op); - else if (!same_type(t1,t2)) - type_op_error ("Arguments to %s must be of the same type.",op); - break; - - case BINOP_LOGICAL_AND: - case BINOP_LOGICAL_OR: - if (!boolean_type(t1) || !boolean_type(t2)) - type_op_error ("Arguments to %s must be of boolean type.",op); - break; - - case BINOP_EQUAL: - if ((pointer_type(t1) && !(pointer_type(t2) || integral_type(t2))) || - (pointer_type(t2) && !(pointer_type(t1) || integral_type(t1)))) - type_op_error ("A pointer can only be compared to an integer or pointer.",op); - else if ((pointer_type(t1) && integral_type(t2)) || - (integral_type(t1) && pointer_type(t2))) - { - warning ("combining integer and pointer.\n"); - break; - } - else if (!simple_type(t1) || !simple_type(t2)) - type_op_error ("Arguments to %s must be of simple type.",op); - else if (!same_type(t1,t2)) - type_op_error ("Arguments to %s must be of the same type.",op); - break; - - case BINOP_REM: - case BINOP_MOD: - if (!integral_type(t1) || !integral_type(t2)) - type_op_error ("Arguments to %s must be of integral type.",op); - break; - - case BINOP_LESS: - case BINOP_GTR: - case BINOP_LEQ: - case BINOP_GEQ: - if (!ordered_type(t1) || !ordered_type(t2)) - type_op_error ("Arguments to %s must be of ordered type.",op); - else if (!same_type(t1,t2)) - type_op_error ("Arguments to %s must be of the same type.",op); - break; - - case BINOP_ASSIGN: - if (pointer_type(t1) && !integral_type(t2)) - type_op_error ("A pointer can only be assigned an integer.",op); - else if (pointer_type(t1) && integral_type(t2)) - { - warning ("combining integer and pointer."); - break; - } - else if (!simple_type(t1) || !simple_type(t2)) - type_op_error ("Arguments to %s must be of simple type.",op); - else if (!same_type(t1,t2)) - type_op_error ("Arguments to %s must be of the same type.",op); - break; - - case BINOP_CONCAT: - /* FIXME: Needs to handle bitstrings as well. */ - if (!(string_type(t1) || character_type(t1) || integral_type(t1)) - || !(string_type(t2) || character_type(t2) || integral_type(t2))) - type_op_error ("Arguments to %s must be strings or characters.", op); - break; - - /* Unary checks -- arg2 is null */ - - case UNOP_LOGICAL_NOT: - if (!boolean_type(t1)) - type_op_error ("Argument to %s must be of boolean type.",op); - break; - - case UNOP_PLUS: - case UNOP_NEG: - if (!numeric_type(t1)) - type_op_error ("Argument to %s must be of numeric type.",op); - break; - - case UNOP_IND: - if (integral_type(t1)) - { - warning ("combining pointer and integer.\n"); - break; - } - else if (!pointer_type(t1)) - type_op_error ("Argument to %s must be a pointer.",op); - break; - - case UNOP_PREINCREMENT: - case UNOP_POSTINCREMENT: - case UNOP_PREDECREMENT: - case UNOP_POSTDECREMENT: - if (!ordered_type(t1)) - type_op_error ("Argument to %s must be of an ordered type.",op); - break; - - default: - /* Ok. The following operators have different meanings in - different languages. */ - switch(current_language->la_language) - { -#ifdef _LANG_c - case language_c: - case language_cplus: - switch(op) - { - case BINOP_DIV: - if (!numeric_type(t1) || !numeric_type(t2)) - type_op_error ("Arguments to %s must be numbers.",op); - break; - } - break; -#endif - -#ifdef _LANG_m2 - case language_m2: - switch(op) - { - case BINOP_DIV: - if (!float_type(t1) || !float_type(t2)) - type_op_error ("Arguments to %s must be floating point numbers.",op); - break; - case BINOP_INTDIV: - if (!integral_type(t1) || !integral_type(t2)) - type_op_error ("Arguments to %s must be of integral type.",op); - break; - } -#endif - -#ifdef _LANG_chill - case language_chill: - error ("Missing Chill support in function binop_type_check.");/*FIXME*/ -#endif - - } - } -} - -#endif /* 0 */ - - -/* This page contains functions for the printing out of - error messages that occur during type- and range- - checking. */ - -/* Prints the format string FMT with the operator as a string - corresponding to the opcode OP. If FATAL is non-zero, then - this is an error and error () is called. Otherwise, it is - a warning and printf() is called. */ -void -op_error (fmt,op,fatal) - char *fmt; - enum exp_opcode op; - int fatal; -{ - if (fatal) - error (fmt,op_string(op)); - else - { - warning (fmt,op_string(op)); - } -} - -/* These are called when a language fails a type- or range-check. - The first argument should be a printf()-style format string, and - the rest of the arguments should be its arguments. If - [type|range]_check is [type|range]_check_on, then return_to_top_level() - is called in the style of error (). Otherwise, the message is prefixed - by the value of warning_pre_print and we do not return to the top level. */ - -void -type_error (va_alist) - va_dcl -{ - va_list args; - char *string; - - if (type_check == type_check_warn) - fprintf_filtered (gdb_stderr, warning_pre_print); - else - error_begin (); - - va_start (args); - string = va_arg (args, char *); - vfprintf_filtered (gdb_stderr, string, args); - fprintf_filtered (gdb_stderr, "\n"); - va_end (args); - if (type_check == type_check_on) - return_to_top_level (RETURN_ERROR); -} - -void -range_error (va_alist) - va_dcl -{ - va_list args; - char *string; - - if (range_check == range_check_warn) - fprintf_filtered (gdb_stderr, warning_pre_print); - else - error_begin (); - - va_start (args); - string = va_arg (args, char *); - vfprintf_filtered (gdb_stderr, string, args); - fprintf_filtered (gdb_stderr, "\n"); - va_end (args); - if (range_check == range_check_on) - return_to_top_level (RETURN_ERROR); -} - - -/* This page contains miscellaneous functions */ - -/* Return the language struct for a given language enum. */ - -const struct language_defn * -language_def(lang) - enum language lang; -{ - int i; - - for (i = 0; i < languages_size; i++) { - if (languages[i]->la_language == lang) { - return languages[i]; - } - } - return NULL; -} - -/* Return the language as a string */ -char * -language_str(lang) - enum language lang; -{ - int i; - - for (i = 0; i < languages_size; i++) { - if (languages[i]->la_language == lang) { - return languages[i]->la_name; - } - } - return "Unknown"; -} - -static void -set_check (ignore, from_tty) - char *ignore; - int from_tty; -{ - printf_unfiltered( -"\"set check\" must be followed by the name of a check subcommand.\n"); - help_list(setchecklist, "set check ", -1, gdb_stdout); -} - -static void -show_check (ignore, from_tty) - char *ignore; - int from_tty; -{ - cmd_show_list(showchecklist, from_tty, ""); -} - -/* Add a language to the set of known languages. */ - -void -add_language (lang) - const struct language_defn *lang; -{ - if (lang->la_magic != LANG_MAGIC) - { - fprintf_unfiltered(gdb_stderr, "Magic number of %s language struct wrong\n", - lang->la_name); - abort(); - } - - if (!languages) - { - languages_allocsize = DEFAULT_ALLOCSIZE; - languages = (const struct language_defn **) xmalloc - (languages_allocsize * sizeof (*languages)); - } - if (languages_size >= languages_allocsize) - { - languages_allocsize *= 2; - languages = (const struct language_defn **) xrealloc ((char *) languages, - languages_allocsize * sizeof (*languages)); - } - languages[languages_size++] = lang; -} - -/* Define the language that is no language. */ - -static int -unk_lang_parser () -{ - return 1; -} - -static void -unk_lang_error (msg) - char *msg; -{ - error ("Attempted to parse an expression with unknown language"); -} - -static void -unk_lang_printchar (c, stream) - register int c; - GDB_FILE *stream; -{ - error ("internal error - unimplemented function unk_lang_printchar called."); -} - -static void -unk_lang_printstr (stream, string, length, force_ellipses) - GDB_FILE *stream; - char *string; - unsigned int length; - int force_ellipses; -{ - error ("internal error - unimplemented function unk_lang_printstr called."); -} - -static struct type * -unk_lang_create_fundamental_type (objfile, typeid) - struct objfile *objfile; - int typeid; -{ - error ("internal error - unimplemented function unk_lang_create_fundamental_type called."); -} - -void -unk_lang_print_type (type, varstring, stream, show, level) - struct type *type; - char *varstring; - GDB_FILE *stream; - int show; - int level; -{ - error ("internal error - unimplemented function unk_lang_print_type called."); -} - -int -unk_lang_val_print (type, valaddr, 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; -{ - error ("internal error - unimplemented function unk_lang_val_print called."); -} - -int -unk_lang_value_print (val, stream, format, pretty) - value_ptr val; - GDB_FILE *stream; - int format; - enum val_prettyprint pretty; -{ - error ("internal error - unimplemented function unk_lang_value_print called."); -} - -static struct type ** const (unknown_builtin_types[]) = { 0 }; -static const struct op_print unk_op_print_tab[] = { - {NULL, OP_NULL, PREC_NULL, 0} -}; - -const struct language_defn unknown_language_defn = { - "unknown", - language_unknown, - &unknown_builtin_types[0], - range_check_off, - type_check_off, - unk_lang_parser, - unk_lang_error, - unk_lang_printchar, /* Print character constant */ - unk_lang_printstr, - 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 */ - unk_lang_value_print, /* Print a top-level value */ - &builtin_type_error, /* longest floating point type */ - {"", "", "", ""}, /* Binary format info */ - {"0%lo", "0", "o", ""}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0x%lx", "0x", "x", ""}, /* Hex format info */ - unk_op_print_tab, /* expression operators for printing */ - LANG_MAGIC -}; - -/* These two structs define fake entries for the "local" and "auto" options. */ -const struct language_defn auto_language_defn = { - "auto", - language_auto, - &unknown_builtin_types[0], - range_check_off, - type_check_off, - unk_lang_parser, - unk_lang_error, - unk_lang_printchar, /* Print character constant */ - unk_lang_printstr, - 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 */ - unk_lang_value_print, /* Print a top-level value */ - &builtin_type_error, /* longest floating point type */ - {"", "", "", ""}, /* Binary format info */ - {"0%lo", "0", "o", ""}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0x%lx", "0x", "x", ""}, /* Hex format info */ - unk_op_print_tab, /* expression operators for printing */ - LANG_MAGIC -}; - -const struct language_defn local_language_defn = { - "local", - language_auto, - &unknown_builtin_types[0], - range_check_off, - type_check_off, - unk_lang_parser, - unk_lang_error, - unk_lang_printchar, /* Print character constant */ - unk_lang_printstr, - 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 */ - unk_lang_value_print, /* Print a top-level value */ - &builtin_type_error, /* longest floating point type */ - {"", "", "", ""}, /* Binary format info */ - {"0%lo", "0", "o", ""}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0x%lx", "0x", "x", ""}, /* Hex format info */ - unk_op_print_tab, /* expression operators for printing */ - LANG_MAGIC -}; - -/* Initialize the language routines */ - -void -_initialize_language() -{ - struct cmd_list_element *set, *show; - - /* GDB commands for language specific stuff */ - - set = add_set_cmd ("language", class_support, var_string_noescape, - (char *)&language, - "Set the current source language.", - &setlist); - show = add_show_from_set (set, &showlist); - set->function.cfunc = set_language_command; - show->function.cfunc = show_language_command; - - add_prefix_cmd ("check", no_class, set_check, - "Set the status of the type/range checker", - &setchecklist, "set check ", 0, &setlist); - add_alias_cmd ("c", "check", no_class, 1, &setlist); - add_alias_cmd ("ch", "check", no_class, 1, &setlist); - - add_prefix_cmd ("check", no_class, show_check, - "Show the status of the type/range checker", - &showchecklist, "show check ", 0, &showlist); - add_alias_cmd ("c", "check", no_class, 1, &showlist); - add_alias_cmd ("ch", "check", no_class, 1, &showlist); - - set = add_set_cmd ("type", class_support, var_string_noescape, - (char *)&type, - "Set type checking. (on/warn/off/auto)", - &setchecklist); - show = add_show_from_set (set, &showchecklist); - set->function.cfunc = set_type_command; - show->function.cfunc = show_type_command; - - set = add_set_cmd ("range", class_support, var_string_noescape, - (char *)&range, - "Set range checking. (on/warn/off/auto)", - &setchecklist); - show = add_show_from_set (set, &showchecklist); - set->function.cfunc = set_range_command; - show->function.cfunc = show_range_command; - - add_language (&unknown_language_defn); - add_language (&local_language_defn); - add_language (&auto_language_defn); - - language = savestring ("auto",strlen("auto")); - range = savestring ("auto",strlen("auto")); - type = savestring ("auto",strlen("auto")); - - /* Have the above take effect */ - - set_language_command (language, 0); - set_type_command (NULL, 0); - set_range_command (NULL, 0); -} diff --git a/gnu/usr.bin/gdb/gdb/language.h b/gnu/usr.bin/gdb/gdb/language.h deleted file mode 100644 index 202d606..0000000 --- a/gnu/usr.bin/gdb/gdb/language.h +++ /dev/null @@ -1,413 +0,0 @@ -/* Source-language-related definitions for GDB. - Copyright 1991, 1992 Free Software Foundation, Inc. - Contributed by the Department of Computer Science at the State University - of New York at Buffalo. - -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 (LANGUAGE_H) -#define LANGUAGE_H 1 - -#ifdef __STDC__ /* Forward decls for prototypes */ -struct value; -struct objfile; -/* enum exp_opcode; ANSI's `wisdom' didn't include forward enum decls. */ -#endif - -/* This used to be included to configure GDB for one or more specific - languages. Now it is shortcutted to configure for all of them. FIXME. */ -/* #include "lang_def.h" */ -#define _LANG_c -#define _LANG_m2 -#define _LANG_chill - -/* range_mode == - range_mode_auto: range_check set automatically to default of language. - range_mode_manual: range_check set manually by user. */ - -extern enum range_mode {range_mode_auto, range_mode_manual} range_mode; - -/* range_check == - range_check_on: Ranges are checked in GDB expressions, producing errors. - range_check_warn: Ranges are checked, producing warnings. - range_check_off: Ranges are not checked in GDB expressions. */ - -extern enum range_check - {range_check_off, range_check_warn, range_check_on} range_check; - -/* type_mode == - type_mode_auto: type_check set automatically to default of language - type_mode_manual: type_check set manually by user. */ - -extern enum type_mode {type_mode_auto, type_mode_manual} type_mode; - -/* type_check == - type_check_on: Types are checked in GDB expressions, producing errors. - type_check_warn: Types are checked, producing warnings. - type_check_off: Types are not checked in GDB expressions. */ - -extern enum type_check - {type_check_off, type_check_warn, type_check_on} type_check; - -/* Information for doing language dependent formatting of printed values. */ - -struct language_format_info -{ - /* The format that can be passed directly to standard C printf functions - to generate a completely formatted value in the format appropriate for - the language. */ - - char *la_format; - - /* The prefix to be used when directly printing a value, or constructing - a standard C printf format. This generally is everything up to the - conversion specification (the part introduced by the '%' character - and terminated by the conversion specifier character). */ - - char *la_format_prefix; - - /* The conversion specifier. This is generally everything after the - field width and precision, typically only a single character such - as 'o' for octal format or 'x' for hexadecimal format. */ - - char *la_format_specifier; - - /* The suffix to be used when directly printing a value, or constructing - a standard C printf format. This generally is everything after the - conversion specification (the part introduced by the '%' character - and terminated by the conversion specifier character). */ - - char *la_format_suffix; /* Suffix for custom format string */ -}; - -/* Structure tying together assorted information about a language. */ - -struct language_defn -{ - /* Name of the language */ - - char *la_name; - - /* its symtab language-enum (defs.h) */ - - enum language la_language; - - /* Its builtin types. This is a vector ended by a NULL pointer. These - types can be specified by name in parsing types in expressions, - regardless of whether the program being debugged actually defines - such a type. */ - - struct type ** const *la_builtin_type_vector; - - /* Default range checking */ - - enum range_check la_range_check; - - /* Default type checking */ - - enum type_check la_type_check; - - /* Parser function. */ - - int (*la_parser) PARAMS((void)); - - /* Parser error function */ - - void (*la_error) PARAMS ((char *)); - - void (*la_printchar) PARAMS ((int, GDB_FILE *)); - - void (*la_printstr) PARAMS ((GDB_FILE *, char *, unsigned int, int)); - - struct type *(*la_fund_type) PARAMS ((struct objfile *, int)); - - /* Print a type using syntax appropriate for this language. */ - - void (*la_print_type) PARAMS ((struct type *, char *, GDB_FILE *, int, int)); - - /* Print a value using syntax appropriate for this language. */ - - int (*la_val_print) PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, - int, int, int, enum val_prettyprint)); - - /* Print a top-level value using syntax appropriate for this language. */ - - int (*la_value_print) PARAMS ((struct value *, GDB_FILE *, - int, enum val_prettyprint)); - - /* Longest floating point type */ - - struct type **la_longest_float; - - /* Base 2 (binary) formats. */ - - struct language_format_info la_binary_format; - - /* Base 8 (octal) formats. */ - - struct language_format_info la_octal_format; - - /* Base 10 (decimal) formats */ - - struct language_format_info la_decimal_format; - - /* Base 16 (hexadecimal) formats */ - - struct language_format_info la_hex_format; - - - /* Table for printing expressions */ - - const struct op_print *la_op_print_tab; - - /* Add fields above this point, so the magic number is always last. */ - /* Magic number for compat checking */ - - long la_magic; - -}; - -#define LANG_MAGIC 910823L - -/* Pointer to the language_defn for our current language. This pointer - always points to *some* valid struct; it can be used without checking - it for validity. - - The current language affects expression parsing and evaluation - (FIXME: it might be cleaner to make the evaluation-related stuff - separate exp_opcodes for each different set of semantics. We - should at least think this through more clearly with respect to - what happens if the language is changed between parsing and - evaluation) and printing of things like types and arrays. It does - *not* affect symbol-reading-- each source file in a symbol-file has - its own language and we should keep track of that regardless of the - language when symbols are read. If we want some manual setting for - the language of symbol files (e.g. detecting when ".c" files are - C++), it should be a seprate setting from the current_language. */ - -extern const struct language_defn *current_language; - -/* Pointer to the language_defn expected by the user, e.g. the language - of main(), or the language we last mentioned in a message, or C. */ - -extern const struct language_defn *expected_language; - -/* language_mode == - language_mode_auto: current_language automatically set upon selection - of scope (e.g. stack frame) - language_mode_manual: current_language set only by user. */ - -extern enum language_mode - {language_mode_auto, language_mode_manual} language_mode; - -/* These macros define the behaviour of the expression - evaluator. */ - -/* Should we strictly type check expressions? */ -#define STRICT_TYPE (type_check != type_check_off) - -/* Should we range check values against the domain of their type? */ -#define RANGE_CHECK (range_check != range_check_off) - -/* "cast" really means conversion */ -/* FIXME -- should be a setting in language_defn */ -#define CAST_IS_CONVERSION (current_language->la_language == language_c || \ - current_language->la_language == language_cplus) - -extern void -language_info PARAMS ((int)); - -extern void -set_language PARAMS ((enum language)); - - -/* This page contains functions that return things that are - specific to languages. Each of these functions is based on - the current setting of working_lang, which the user sets - with the "set language" command. */ - -/* Returns some built-in types */ -#define longest_float() (*current_language->la_longest_float) - -#define create_fundamental_type(objfile,typeid) \ - (current_language->la_fund_type(objfile, typeid)) - -#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, \ - recurse,pretty)) -#define LA_VALUE_PRINT(val,stream,fmt,pretty) \ - (current_language->la_value_print(val,stream,fmt,pretty)) - -/* Return a format string for printf that will print a number in one of - the local (language-specific) formats. Result is static and is - overwritten by the next call. Takes printf options like "08" or "l" - (to produce e.g. %08x or %lx). */ - -#define local_binary_format() \ - (current_language->la_binary_format.la_format) -#define local_binary_format_prefix() \ - (current_language->la_binary_format.la_format_prefix) -#define local_binary_format_specifier() \ - (current_language->la_binary_format.la_format_specifier) -#define local_binary_format_suffix() \ - (current_language->la_binary_format.la_format_suffix) - -#define local_octal_format() \ - (current_language->la_octal_format.la_format) -#define local_octal_format_prefix() \ - (current_language->la_octal_format.la_format_prefix) -#define local_octal_format_specifier() \ - (current_language->la_octal_format.la_format_specifier) -#define local_octal_format_suffix() \ - (current_language->la_octal_format.la_format_suffix) - -#define local_decimal_format() \ - (current_language->la_decimal_format.la_format) -#define local_decimal_format_prefix() \ - (current_language->la_decimal_format.la_format_prefix) -#define local_decimal_format_specifier() \ - (current_language->la_decimal_format.la_format_specifier) -#define local_decimal_format_suffix() \ - (current_language->la_decimal_format.la_format_suffix) - -#define local_hex_format() \ - (current_language->la_hex_format.la_format) -#define local_hex_format_prefix() \ - (current_language->la_hex_format.la_format_prefix) -#define local_hex_format_specifier() \ - (current_language->la_hex_format.la_format_specifier) -#define local_hex_format_suffix() \ - (current_language->la_hex_format.la_format_suffix) - -#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)) - -/* Test a character to decide whether it can be printed in literal form - or needs to be printed in another representation. For example, - in C the literal form of the character with octal value 141 is 'a' - 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)) - -/* Return a format string for printf that will print a number in one of - the local (language-specific) formats. Result is static and is - overwritten by the next call. Takes printf options like "08" or "l" - (to produce e.g. %08x or %lx). */ - -extern char * -local_decimal_format_custom PARAMS ((char *)); /* language.c */ - -extern char * -local_octal_format_custom PARAMS ((char *)); /* language.c */ - -extern char * -local_hex_format_custom PARAMS ((char *)); /* language.c */ - -/* Return a string that contains a number formatted in one of the local - (language-specific) formats. Result is static and is overwritten by - the next call. Takes printf options like "08" or "l". */ - -extern char * -local_hex_string PARAMS ((unsigned long)); /* language.c */ - -extern char * -local_hex_string_custom PARAMS ((unsigned long, char *)); /* language.c */ - -/* Type predicates */ - -extern int -simple_type PARAMS ((struct type *)); - -extern int -ordered_type PARAMS ((struct type *)); - -extern int -same_type PARAMS ((struct type *, struct type *)); - -extern int -integral_type PARAMS ((struct type *)); - -extern int -numeric_type PARAMS ((struct type *)); - -extern int -character_type PARAMS ((struct type *)); - -extern int -boolean_type PARAMS ((struct type *)); - -extern int -float_type PARAMS ((struct type *)); - -extern int -pointer_type PARAMS ((struct type *)); - -extern int -structured_type PARAMS ((struct type *)); - -/* Checks Binary and Unary operations for semantic type correctness */ -/* FIXME: Does not appear to be used */ -#define unop_type_check(v,o) binop_type_check((v),NULL,(o)) - -extern void -binop_type_check PARAMS ((struct value *, struct value *, int)); - -/* Error messages */ - -extern void -op_error PARAMS ((char *fmt, enum exp_opcode, int)); - -#define type_op_error(f,o) \ - op_error((f),(o),type_check==type_check_on ? 1 : 0) -#define range_op_error(f,o) \ - op_error((f),(o),range_check==range_check_on ? 1 : 0) - -extern void -type_error (); - -void -range_error (); - -/* Data: Does this value represent "truth" to the current language? */ - -extern int -value_true PARAMS ((struct value *)); - -/* Misc: The string representing a particular enum language. */ - -extern const struct language_defn * -language_def PARAMS ((enum language)); - -extern char * -language_str PARAMS ((enum language)); - -/* Add a language to the set known by GDB (at initialization time). */ - -extern void -add_language PARAMS ((const struct language_defn *)); - -extern enum language -get_frame_language PARAMS ((void)); /* In stack.c */ - -#endif /* defined (LANGUAGE_H) */ diff --git a/gnu/usr.bin/gdb/gdb/libiberty.h b/gnu/usr.bin/gdb/gdb/libiberty.h deleted file mode 100644 index 9854b4c..0000000 --- a/gnu/usr.bin/gdb/gdb/libiberty.h +++ /dev/null @@ -1,107 +0,0 @@ -/* Function declarations for libiberty. - Written by Cygnus Support, 1994. - - The libiberty library provides a number of functions which are - missing on some operating systems. We do not declare those here, - to avoid conflicts with the system header files on operating - systems that do support those functions. In this file we only - declare those functions which are specific to libiberty. */ - -#ifndef LIBIBERTY_H -#define LIBIBERTY_H - -#include "ansidecl.h" - -/* Build an argument vector from a string. Allocates memory using - malloc. Use freeargv to free the vector. */ - -extern char **buildargv PARAMS ((char *)); - -/* Free a vector returned by buildargv. */ - -extern void freeargv PARAMS ((char **)); - -/* Return the last component of a path name. */ - -extern char *basename PARAMS ((char *)); - -/* Concatenate an arbitrary number of strings, up to (char *) NULL. - Allocates memory using xmalloc. */ - -extern char *concat PARAMS ((const char *, ...)); - -/* Check whether two file descriptors refer to the same file. */ - -extern int fdmatch PARAMS ((int fd1, int fd2)); - -/* Get the amount of time the process has run, in microseconds. */ - -extern long get_run_time PARAMS ((void)); - -/* Allocate memory filled with spaces. Allocates using malloc. */ - -extern const char *spaces PARAMS ((int count)); - -/* Return the maximum error number for which strerror will return a - string. */ - -extern int errno_max PARAMS ((void)); - -/* Return the name of an errno value (e.g., strerrno (EINVAL) returns - "EINVAL"). */ - -extern const char *strerrno PARAMS ((int)); - -/* Given the name of an errno value, return the value. */ - -extern int strtoerrno PARAMS ((const char *)); - -/* Return the maximum signal number for which strsignal will return a - string. */ - -extern int signo_max PARAMS ((void)); - -/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns - "SIGHUP"). */ - -extern const char *strsigno PARAMS ((int)); - -/* Given the name of a signal, return its number. */ - -extern int strtosigno PARAMS ((const char *)); - -/* Register a function to be run by xexit. Returns 0 on success. */ - -extern int xatexit PARAMS ((void (*fn) (void))); - -/* Exit, calling all the functions registered with xatexit. */ - -#ifndef __GNUC__ -extern void xexit PARAMS ((int status)); -#else -typedef void libiberty_voidfn PARAMS ((int status)); -__volatile__ libiberty_voidfn xexit; -#endif - -/* Set the program name used by xmalloc. */ - -extern void xmalloc_set_program_name PARAMS ((const char *)); - -/* Allocate memory without fail. If malloc fails, this will print a - message to stderr (using the name set by xmalloc_set_program_name, - if any) and then call xexit. - - FIXME: We do not declare the parameter type (size_t) in order to - avoid conflicts with other declarations of xmalloc that exist in - programs which use libiberty. */ - -extern PTR xmalloc (); - -/* Reallocate memory without fail. This works like xmalloc. - - FIXME: We do not declare the parameter types for the same reason as - xmalloc. */ - -extern PTR xrealloc (); - -#endif /* ! defined (LIBIBERTY_H) */ diff --git a/gnu/usr.bin/gdb/gdb/m2-exp.y b/gnu/usr.bin/gdb/gdb/m2-exp.y deleted file mode 100644 index cc4001f..0000000 --- a/gnu/usr.bin/gdb/gdb/m2-exp.y +++ /dev/null @@ -1,1169 +0,0 @@ -/* YACC grammar for Modula-2 expressions, for GDB. - Copyright (C) 1986, 1989, 1990, 1991 Free Software Foundation, Inc. - Generated from expread.y (now c-exp.y) and contributed by the Department - of Computer Science at the State University of New York at Buffalo, 1991. - -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. */ - -/* Parse a Modula-2 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. - - 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 ( and for example) just became - too messy, particularly when such includes can be inserted at random - times by the parser generator. */ - -%{ - -#include "defs.h" -#include "expression.h" -#include "language.h" -#include "value.h" -#include "parser-defs.h" -#include "m2-lang.h" - -/* 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 m2_maxdepth -#define yyparse m2_parse -#define yylex m2_lex -#define yyerror m2_error -#define yylval m2_lval -#define yychar m2_char -#define yydebug m2_debug -#define yypact m2_pact -#define yyr1 m2_r1 -#define yyr2 m2_r2 -#define yydef m2_def -#define yychk m2_chk -#define yypgo m2_pgo -#define yyact m2_act -#define yyexca m2_exca -#define yyerrflag m2_errflag -#define yynerrs m2_nerrs -#define yyps m2_ps -#define yypv m2_pv -#define yys m2_s -#define yy_yys m2_yys -#define yystate m2_state -#define yytmp m2_tmp -#define yyv m2_v -#define yy_yyv m2_yyv -#define yyval m2_val -#define yylloc m2_lloc -#define yyreds m2_reds /* With YYDEBUG defined */ -#define yytoks m2_toks /* With YYDEBUG defined */ - -#ifndef YYDEBUG -#define YYDEBUG 0 /* Default to no yydebug support */ -#endif - -int -yyparse PARAMS ((void)); - -static int -yylex PARAMS ((void)); - -void -yyerror PARAMS ((char *)); - -#if 0 -static char * -make_qualname PARAMS ((char *, char *)); -#endif - -static int -parse_number PARAMS ((int)); - -/* The sign of the number being parsed. */ -static int number_sign = 1; - -/* The block that the module specified by the qualifer on an identifer is - contained in, */ -#if 0 -static struct block *modblock=0; -#endif - -%} - -/* 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; - unsigned LONGEST ulval; - double dval; - struct symbol *sym; - struct type *tval; - struct stoken sval; - int voidval; - struct block *bval; - enum exp_opcode opcode; - struct internalvar *ivar; - - struct type **tvec; - int *ivec; - } - -%type exp type_exp start set -%type variable -%type type -%type block -%type fblock - -%token INT HEX ERROR -%token UINT M2_TRUE M2_FALSE CHAR -%token FLOAT - -/* Both NAME and TYPENAME tokens represent symbols in the input, - and both convey their data as strings. - But a TYPENAME is a string that happens to be defined as a typedef - or builtin type name (such as int or char) - and a NAME is any other symbol. - - Contexts where this distinction is not important can use the - nonterminal "name", which matches either NAME or TYPENAME. */ - -%token STRING -%token NAME BLOCKNAME IDENT VARNAME -%token TYPENAME - -%token SIZE CAP ORD HIGH ABS MIN_FUNC MAX_FUNC FLOAT_FUNC VAL CHR ODD TRUNC -%token INC DEC INCL EXCL - -/* The GDB scope operator */ -%token COLONCOLON - -%token LAST REGNAME - -%token INTERNAL_VAR - -/* M2 tokens */ -%left ',' -%left ABOVE_COMMA -%nonassoc ASSIGN -%left '<' '>' LEQ GEQ '=' NOTEQUAL '#' IN -%left OROR -%left LOGICAL_AND '&' -%left '@' -%left '+' '-' -%left '*' '/' DIV MOD -%right UNARY -%right '^' DOT '[' '(' -%right NOT '~' -%left COLONCOLON QID -/* This is not an actual token ; it is used for precedence. -%right QID -*/ - - -%% - -start : exp - | type_exp - ; - -type_exp: type - { write_exp_elt_opcode(OP_TYPE); - write_exp_elt_type($1); - write_exp_elt_opcode(OP_TYPE); - } - ; - -/* Expressions */ - -exp : exp '^' %prec UNARY - { write_exp_elt_opcode (UNOP_IND); } - -exp : '-' - { number_sign = -1; } - exp %prec UNARY - { number_sign = 1; - write_exp_elt_opcode (UNOP_NEG); } - ; - -exp : '+' exp %prec UNARY - { write_exp_elt_opcode(UNOP_PLUS); } - ; - -exp : not_exp exp %prec UNARY - { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } - ; - -not_exp : NOT - | '~' - ; - -exp : CAP '(' exp ')' - { write_exp_elt_opcode (UNOP_CAP); } - ; - -exp : ORD '(' exp ')' - { write_exp_elt_opcode (UNOP_ORD); } - ; - -exp : ABS '(' exp ')' - { write_exp_elt_opcode (UNOP_ABS); } - ; - -exp : HIGH '(' exp ')' - { write_exp_elt_opcode (UNOP_HIGH); } - ; - -exp : MIN_FUNC '(' type ')' - { write_exp_elt_opcode (UNOP_MIN); - write_exp_elt_type ($3); - write_exp_elt_opcode (UNOP_MIN); } - ; - -exp : MAX_FUNC '(' type ')' - { write_exp_elt_opcode (UNOP_MAX); - write_exp_elt_type ($3); - write_exp_elt_opcode (UNOP_MIN); } - ; - -exp : FLOAT_FUNC '(' exp ')' - { write_exp_elt_opcode (UNOP_FLOAT); } - ; - -exp : VAL '(' type ',' exp ')' - { write_exp_elt_opcode (BINOP_VAL); - write_exp_elt_type ($3); - write_exp_elt_opcode (BINOP_VAL); } - ; - -exp : CHR '(' exp ')' - { write_exp_elt_opcode (UNOP_CHR); } - ; - -exp : ODD '(' exp ')' - { write_exp_elt_opcode (UNOP_ODD); } - ; - -exp : TRUNC '(' exp ')' - { write_exp_elt_opcode (UNOP_TRUNC); } - ; - -exp : SIZE exp %prec UNARY - { write_exp_elt_opcode (UNOP_SIZEOF); } - ; - - -exp : INC '(' exp ')' - { write_exp_elt_opcode(UNOP_PREINCREMENT); } - ; - -exp : INC '(' exp ',' exp ')' - { write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode(BINOP_ADD); - write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); } - ; - -exp : DEC '(' exp ')' - { write_exp_elt_opcode(UNOP_PREDECREMENT);} - ; - -exp : DEC '(' exp ',' exp ')' - { write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); - write_exp_elt_opcode(BINOP_SUB); - write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); } - ; - -exp : exp DOT NAME - { write_exp_elt_opcode (STRUCTOP_STRUCT); - write_exp_string ($3); - write_exp_elt_opcode (STRUCTOP_STRUCT); } - ; - -exp : set - ; - -exp : exp IN set - { error("Sets are not implemented.");} - ; - -exp : INCL '(' exp ',' exp ')' - { error("Sets are not implemented.");} - ; - -exp : EXCL '(' exp ',' exp ')' - { error("Sets are not implemented.");} - -set : '{' arglist '}' - { error("Sets are not implemented.");} - | type '{' arglist '}' - { error("Sets are not implemented.");} - ; - - -/* Modula-2 array subscript notation [a,b,c...] */ -exp : exp '[' - /* This function just saves the number of arguments - that follow in the list. It is *not* specific to - function types */ - { start_arglist(); } - non_empty_arglist ']' %prec DOT - { write_exp_elt_opcode (MULTI_SUBSCRIPT); - write_exp_elt_longcst ((LONGEST) end_arglist()); - write_exp_elt_opcode (MULTI_SUBSCRIPT); } - ; - -exp : exp '(' - /* This is to save the value of arglist_len - being accumulated by an outer function call. */ - { start_arglist (); } - arglist ')' %prec DOT - { write_exp_elt_opcode (OP_FUNCALL); - write_exp_elt_longcst ((LONGEST) end_arglist ()); - write_exp_elt_opcode (OP_FUNCALL); } - ; - -arglist : - ; - -arglist : exp - { arglist_len = 1; } - ; - -arglist : arglist ',' exp %prec ABOVE_COMMA - { arglist_len++; } - ; - -non_empty_arglist - : exp - { arglist_len = 1; } - ; - -non_empty_arglist - : non_empty_arglist ',' exp %prec ABOVE_COMMA - { arglist_len++; } - ; - -/* GDB construct */ -exp : '{' type '}' exp %prec UNARY - { write_exp_elt_opcode (UNOP_MEMVAL); - write_exp_elt_type ($2); - write_exp_elt_opcode (UNOP_MEMVAL); } - ; - -exp : type '(' exp ')' %prec UNARY - { write_exp_elt_opcode (UNOP_CAST); - write_exp_elt_type ($1); - write_exp_elt_opcode (UNOP_CAST); } - ; - -exp : '(' exp ')' - { } - ; - -/* Binary operators in order of decreasing precedence. Note that some - of these operators are overloaded! (ie. sets) */ - -/* GDB construct */ -exp : exp '@' exp - { write_exp_elt_opcode (BINOP_REPEAT); } - ; - -exp : exp '*' exp - { write_exp_elt_opcode (BINOP_MUL); } - ; - -exp : exp '/' exp - { write_exp_elt_opcode (BINOP_DIV); } - ; - -exp : exp DIV exp - { write_exp_elt_opcode (BINOP_INTDIV); } - ; - -exp : exp MOD exp - { write_exp_elt_opcode (BINOP_REM); } - ; - -exp : exp '+' exp - { write_exp_elt_opcode (BINOP_ADD); } - ; - -exp : exp '-' exp - { write_exp_elt_opcode (BINOP_SUB); } - ; - -exp : exp '=' exp - { write_exp_elt_opcode (BINOP_EQUAL); } - ; - -exp : exp NOTEQUAL exp - { write_exp_elt_opcode (BINOP_NOTEQUAL); } - | exp '#' exp - { write_exp_elt_opcode (BINOP_NOTEQUAL); } - ; - -exp : exp LEQ exp - { write_exp_elt_opcode (BINOP_LEQ); } - ; - -exp : exp GEQ exp - { write_exp_elt_opcode (BINOP_GEQ); } - ; - -exp : exp '<' exp - { write_exp_elt_opcode (BINOP_LESS); } - ; - -exp : exp '>' exp - { write_exp_elt_opcode (BINOP_GTR); } - ; - -exp : exp LOGICAL_AND exp - { write_exp_elt_opcode (BINOP_LOGICAL_AND); } - ; - -exp : exp OROR exp - { write_exp_elt_opcode (BINOP_LOGICAL_OR); } - ; - -exp : exp ASSIGN exp - { write_exp_elt_opcode (BINOP_ASSIGN); } - ; - - -/* Constants */ - -exp : M2_TRUE - { write_exp_elt_opcode (OP_BOOL); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_BOOL); } - ; - -exp : M2_FALSE - { write_exp_elt_opcode (OP_BOOL); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_BOOL); } - ; - -exp : INT - { write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_m2_int); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_LONG); } - ; - -exp : UINT - { - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_m2_card); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_LONG); - } - ; - -exp : CHAR - { write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_m2_char); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_LONG); } - ; - - -exp : FLOAT - { write_exp_elt_opcode (OP_DOUBLE); - write_exp_elt_type (builtin_type_m2_real); - write_exp_elt_dblcst ($1); - write_exp_elt_opcode (OP_DOUBLE); } - ; - -exp : variable - ; - -/* The GDB internal variable $$, et al. */ -exp : LAST - { write_exp_elt_opcode (OP_LAST); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_LAST); } - ; - -exp : REGNAME - { write_exp_elt_opcode (OP_REGISTER); - write_exp_elt_longcst ((LONGEST) $1); - write_exp_elt_opcode (OP_REGISTER); } - ; - -exp : SIZE '(' type ')' %prec UNARY - { write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_int); - write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3)); - write_exp_elt_opcode (OP_LONG); } - ; - -exp : STRING - { write_exp_elt_opcode (OP_M2_STRING); - write_exp_string ($1); - write_exp_elt_opcode (OP_M2_STRING); } - ; - -/* This will be used for extensions later. Like adding modules. */ -block : fblock - { $$ = SYMBOL_BLOCK_VALUE($1); } - ; - -fblock : BLOCKNAME - { struct symbol *sym - = lookup_symbol (copy_name ($1), expression_context_block, - VAR_NAMESPACE, 0, NULL); - $$ = sym;} - ; - - -/* GDB scope operator */ -fblock : block COLONCOLON BLOCKNAME - { struct symbol *tem - = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, 0, NULL); - if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) - error ("No function \"%s\" in specified context.", - copy_name ($3)); - $$ = tem; - } - ; - -/* Useful for assigning to PROCEDURE variables */ -variable: fblock - { write_exp_elt_opcode(OP_VAR_VALUE); - write_exp_elt_block (NULL); - write_exp_elt_sym ($1); - write_exp_elt_opcode (OP_VAR_VALUE); } - ; - -/* GDB internal ($foo) variable */ -variable: INTERNAL_VAR - { write_exp_elt_opcode (OP_INTERNALVAR); - write_exp_elt_intern ($1); - write_exp_elt_opcode (OP_INTERNALVAR); } - ; - -/* GDB scope operator */ -variable: block COLONCOLON NAME - { struct symbol *sym; - sym = lookup_symbol (copy_name ($3), $1, - VAR_NAMESPACE, 0, NULL); - if (sym == 0) - error ("No symbol \"%s\" in specified context.", - copy_name ($3)); - - write_exp_elt_opcode (OP_VAR_VALUE); - /* block_found is set by lookup_symbol. */ - write_exp_elt_block (block_found); - write_exp_elt_sym (sym); - write_exp_elt_opcode (OP_VAR_VALUE); } - ; - -/* Base case for variables. */ -variable: NAME - { struct symbol *sym; - int is_a_field_of_this; - - sym = lookup_symbol (copy_name ($1), - expression_context_block, - VAR_NAMESPACE, - &is_a_field_of_this, - NULL); - if (sym) - { - 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); - } - else - { - struct minimal_symbol *msymbol; - register char *arg = copy_name ($1); - - msymbol = lookup_minimal_symbol (arg, - (struct objfile *) NULL); - if (msymbol != NULL) - { - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (builtin_type_long); - write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol)); - write_exp_elt_opcode (OP_LONG); - write_exp_elt_opcode (UNOP_MEMVAL); - if (msymbol -> type == mst_data || - msymbol -> type == mst_bss) - write_exp_elt_type (builtin_type_int); - else if (msymbol -> type == mst_text) - write_exp_elt_type (lookup_function_type (builtin_type_int)); - else - write_exp_elt_type (builtin_type_char); - write_exp_elt_opcode (UNOP_MEMVAL); - } - else if (!have_full_symbols () && !have_partial_symbols ()) - error ("No symbol table is loaded. Use the \"symbol-file\" command."); - else - error ("No symbol \"%s\" in current context.", - copy_name ($1)); - } - } - ; - -type - : TYPENAME - { $$ = lookup_typename (copy_name ($1), - expression_context_block, 0); } - - ; - -%% - -#if 0 /* FIXME! */ -int -overflow(a,b) - long a,b; -{ - return (MAX_OF_TYPE(builtin_type_m2_int) - b) < a; -} - -int -uoverflow(a,b) - unsigned long a,b; -{ - return (MAX_OF_TYPE(builtin_type_m2_card) - b) < a; -} -#endif /* FIXME */ - -/* 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 (olen) - int olen; -{ - register char *p = lexptr; - register LONGEST n = 0; - register LONGEST prevn = 0; - register int c,i,ischar=0; - register int base = input_radix; - register int len = olen; - int unsigned_p = number_sign == 1 ? 1 : 0; - - if(p[len-1] == 'H') - { - base = 16; - len--; - } - else if(p[len-1] == 'C' || p[len-1] == 'B') - { - base = 8; - ischar = p[len-1] == 'C'; - len--; - } - - /* Scan the number */ - for (c = 0; c < len; c++) - { - if (p[c] == '.' && base == 10) - { - /* It's a float since it contains a point. */ - yylval.dval = atof (p); - lexptr += len; - return FLOAT; - } - if (p[c] == '.' && base != 10) - error("Floating point numbers must be base 10."); - if (base == 10 && (p[c] < '0' || p[c] > '9')) - error("Invalid digit \'%c\' in number.",p[c]); - } - - while (len-- > 0) - { - c = *p++; - n *= base; - if( base == 8 && (c == '8' || c == '9')) - error("Invalid digit \'%c\' in octal number.",c); - if (c >= '0' && c <= '9') - i = c - '0'; - else - { - if (base == 16 && c >= 'A' && c <= 'F') - i = c - 'A' + 10; - else - return ERROR; - } - n+=i; - if(i >= base) - return ERROR; - if(!unsigned_p && number_sign == 1 && (prevn >= n)) - unsigned_p=1; /* Try something unsigned */ - /* Don't do the range check if n==i and i==0, since that special - case will give an overflow error. */ - if(RANGE_CHECK && n!=i && i) - { - if((unsigned_p && (unsigned)prevn >= (unsigned)n) || - ((!unsigned_p && number_sign==-1) && -prevn <= -n)) - range_error("Overflow on numeric constant."); - } - prevn=n; - } - - lexptr = p; - if(*p == 'B' || *p == 'C' || *p == 'H') - lexptr++; /* Advance past B,C or H */ - - if (ischar) - { - yylval.ulval = n; - return CHAR; - } - else if ( unsigned_p && number_sign == 1) - { - yylval.ulval = n; - return UINT; - } - else if((unsigned_p && (n<0))) { - range_error("Overflow on numeric constant -- number too large."); - /* But, this can return if range_check == range_warn. */ - } - yylval.lval = n; - return INT; -} - - -/* Some tokens */ - -static struct -{ - char name[2]; - int token; -} tokentab2[] = -{ - { {'<', '>'}, NOTEQUAL }, - { {':', '='}, ASSIGN }, - { {'<', '='}, LEQ }, - { {'>', '='}, GEQ }, - { {':', ':'}, COLONCOLON }, - -}; - -/* Some specific keywords */ - -struct keyword { - char keyw[10]; - int token; -}; - -static struct keyword keytab[] = -{ - {"OR" , OROR }, - {"IN", IN },/* Note space after IN */ - {"AND", LOGICAL_AND}, - {"ABS", ABS }, - {"CHR", CHR }, - {"DEC", DEC }, - {"NOT", NOT }, - {"DIV", DIV }, - {"INC", INC }, - {"MAX", MAX_FUNC }, - {"MIN", MIN_FUNC }, - {"MOD", MOD }, - {"ODD", ODD }, - {"CAP", CAP }, - {"ORD", ORD }, - {"VAL", VAL }, - {"EXCL", EXCL }, - {"HIGH", HIGH }, - {"INCL", INCL }, - {"SIZE", SIZE }, - {"FLOAT", FLOAT_FUNC }, - {"TRUNC", TRUNC }, -}; - - -/* Read one token, getting characters through lexptr. */ - -/* This is where we will check to make sure that the language and the operators used are - compatible */ - -static int -yylex () -{ - register int c; - register int namelen; - register int i; - register char *tokstart; - register char quote; - - retry: - - tokstart = lexptr; - - - /* See if it is a special token of length 2 */ - for( i = 0 ; i < sizeof tokentab2 / sizeof tokentab2[0] ; i++) - if(STREQN(tokentab2[i].name, tokstart, 2)) - { - lexptr += 2; - return tokentab2[i].token; - } - - switch (c = *tokstart) - { - case 0: - return 0; - - case ' ': - case '\t': - case '\n': - lexptr++; - goto retry; - - 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') - break; /* Falls into number code. */ - else - { - lexptr++; - return DOT; - } - -/* These are character tokens that appear as-is in the YACC grammar */ - case '+': - case '-': - case '*': - case '/': - case '^': - case '<': - case '>': - case '[': - case ']': - case '=': - case '{': - case '}': - case '#': - case '@': - case '~': - case '&': - lexptr++; - return c; - - case '\'' : - case '"': - quote = c; - for (namelen = 1; (c = tokstart[namelen]) != quote && c != '\0'; namelen++) - if (c == '\\') - { - c = tokstart[++namelen]; - if (c >= '0' && c <= '9') - { - c = tokstart[++namelen]; - if (c >= '0' && c <= '9') - c = tokstart[++namelen]; - } - } - if(c != quote) - error("Unterminated string or character constant."); - yylval.sval.ptr = tokstart + 1; - yylval.sval.length = namelen - 1; - lexptr += namelen + 1; - - if(namelen == 2) /* Single character */ - { - yylval.ulval = tokstart[1]; - return CHAR; - } - else - return STRING; - } - - /* Is it a number? */ - /* Note: We have already dealt with the case of the token '.'. - See case '.' above. */ - if ((c >= '0' && c <= '9')) - { - /* It's a number. */ - int got_dot = 0, got_e = 0; - register char *p = tokstart; - int toktype; - - for (++p ;; ++p) - { - if (!got_e && (*p == 'e' || *p == 'E')) - got_dot = got_e = 1; - 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; - else if ((*p < '0' || *p > '9') && - (*p < 'A' || *p > 'F') && - (*p != 'H')) /* Modula-2 hexadecimal number */ - break; - } - toktype = parse_number (p - tokstart); - 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; - } - - 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 = 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; - - /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1) - and $$digits (equivalent to $<-digits> if you could type that). - Make token type LAST, and put the number (the digits) in yylval. */ - - if (*tokstart == '$') - { - register int negate = 0; - c = 1; - /* Double dollar means negate the number and add -1 as well. - Thus $$ alone means -1. */ - if (namelen >= 2 && tokstart[1] == '$') - { - negate = 1; - c = 2; - } - if (c == namelen) - { - /* Just dollars (one or two) */ - yylval.lval = - negate; - return LAST; - } - /* Is the rest of the token digits? */ - for (; c < namelen; c++) - if (!(tokstart[c] >= '0' && tokstart[c] <= '9')) - break; - if (c == namelen) - { - yylval.lval = atoi (tokstart + 1 + negate); - if (negate) - yylval.lval = - yylval.lval; - return LAST; - } - } - - /* Handle tokens that refer to machine registers: - $ followed by a register name. */ - - if (*tokstart == '$') { - for (c = 0; c < NUM_REGS; c++) - if (namelen - 1 == strlen (reg_names[c]) - && STREQN (tokstart + 1, reg_names[c], namelen - 1)) - { - yylval.lval = c; - return REGNAME; - } - for (c = 0; c < num_std_regs; c++) - if (namelen - 1 == strlen (std_regs[c].name) - && STREQN (tokstart + 1, std_regs[c].name, namelen - 1)) - { - yylval.lval = std_regs[c].regnum; - return REGNAME; - } - } - - - /* Lookup special keywords */ - for(i = 0 ; i < sizeof(keytab) / sizeof(keytab[0]) ; i++) - if(namelen == strlen(keytab[i].keyw) && STREQN(tokstart,keytab[i].keyw,namelen)) - return keytab[i].token; - - yylval.sval.ptr = tokstart; - yylval.sval.length = namelen; - - /* Any other names starting in $ are debugger internal variables. */ - - if (*tokstart == '$') - { - yylval.ivar = (struct internalvar *) lookup_internalvar (copy_name (yylval.sval) + 1); - return INTERNAL_VAR; - } - - - /* Use token-type BLOCKNAME for symbols that happen to be defined as - functions. If this is not so, then ... - Use token-type TYPENAME for symbols that happen to be defined - currently as names of types; NAME for other symbols. - The caller is not constrained to care about the distinction. */ - { - - - char *tmp = copy_name (yylval.sval); - struct symbol *sym; - - if (lookup_partial_symtab (tmp)) - return BLOCKNAME; - sym = lookup_symbol (tmp, expression_context_block, - VAR_NAMESPACE, 0, NULL); - if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) - return BLOCKNAME; - if (lookup_typename (copy_name (yylval.sval), expression_context_block, 1)) - return TYPENAME; - - if(sym) - { - switch(sym->class) - { - case LOC_STATIC: - case LOC_REGISTER: - case LOC_ARG: - case LOC_REF_ARG: - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_LOCAL: - case LOC_LOCAL_ARG: - case LOC_BASEREG: - case LOC_BASEREG_ARG: - case LOC_CONST: - case LOC_CONST_BYTES: - case LOC_OPTIMIZED_OUT: - return NAME; - - case LOC_TYPEDEF: - return TYPENAME; - - case LOC_BLOCK: - return BLOCKNAME; - - case LOC_UNDEF: - error("internal: Undefined class in m2lex()"); - - case LOC_LABEL: - error("internal: Unforseen case in m2lex()"); - } - } - else - { - /* Built-in BOOLEAN type. This is sort of a hack. */ - if(STREQN(tokstart,"TRUE",4)) - { - yylval.ulval = 1; - return M2_TRUE; - } - else if(STREQN(tokstart,"FALSE",5)) - { - yylval.ulval = 0; - return M2_FALSE; - } - } - - /* Must be another type of name... */ - return NAME; - } -} - -#if 0 /* Unused */ -static char * -make_qualname(mod,ident) - char *mod, *ident; -{ - char *new = malloc(strlen(mod)+strlen(ident)+2); - - strcpy(new,mod); - strcat(new,"."); - strcat(new,ident); - return new; -} -#endif /* 0 */ - -void -yyerror(msg) - char *msg; /* unused */ -{ - printf("Parsing: %s\n",lexptr); - if (yychar < 256) - error("Invalid syntax in expression near character '%c'.",yychar); - else - error("Invalid syntax in expression"); -} - diff --git a/gnu/usr.bin/gdb/gdb/m2-lang.c b/gnu/usr.bin/gdb/gdb/m2-lang.c deleted file mode 100644 index 6e15d30..0000000 --- a/gnu/usr.bin/gdb/gdb/m2-lang.c +++ /dev/null @@ -1,447 +0,0 @@ -/* Modula 2 language support routines for GDB, the GNU debugger. - Copyright 1992 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 "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "parser-defs.h" -#include "language.h" -#include "m2-lang.h" -#include "c-lang.h" - -/* 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. - FIXME: This is a copy of the same function from c-exp.y. It should - be replaced with a true Modula version. - */ - -static void -emit_char (c, stream, quoter) - register int c; - GDB_FILE *stream; - int quoter; -{ - - c &= 0xFF; /* Avoid sign bit follies */ - - if (PRINT_LITERAL_FORM (c)) - { - if (c == '\\' || c == quoter) - { - fputs_filtered ("\\", stream); - } - fprintf_filtered (stream, "%c", c); - } - else - { - switch (c) - { - case '\n': - fputs_filtered ("\\n", stream); - break; - case '\b': - fputs_filtered ("\\b", stream); - break; - case '\t': - fputs_filtered ("\\t", stream); - break; - case '\f': - fputs_filtered ("\\f", stream); - break; - case '\r': - fputs_filtered ("\\r", stream); - break; - case '\033': - fputs_filtered ("\\e", stream); - break; - case '\007': - fputs_filtered ("\\a", stream); - break; - default: - fprintf_filtered (stream, "\\%.3o", (unsigned int) c); - break; - } - } -} - -/* FIXME: This is a copy of the same function from c-exp.y. It should - be replaced with a true Modula version. */ - -static void -m2_printchar (c, stream) - int c; - GDB_FILE *stream; -{ - fputs_filtered ("'", stream); - emit_char (c, stream, '\''); - fputs_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. - FIXME: This is a copy of the same function from c-exp.y. It should - be replaced with a true Modula version. */ - -static void -m2_printstr (stream, string, length, force_ellipses) - GDB_FILE *stream; - char *string; - unsigned int length; - int force_ellipses; -{ - register unsigned int i; - unsigned int things_printed = 0; - int in_quotes = 0; - int need_comma = 0; - extern int inspect_it; - extern int repeat_count_threshold; - extern int print_max; - - if (length == 0) - { - fputs_filtered ("\"\"", gdb_stdout); - return; - } - - for (i = 0; i < length && things_printed < print_max; ++i) - { - /* Position of the character we are examining - to see whether it is repeated. */ - unsigned int rep1; - /* Number of repetitions we have detected so far. */ - unsigned int reps; - - QUIT; - - if (need_comma) - { - fputs_filtered (", ", stream); - need_comma = 0; - } - - rep1 = i + 1; - reps = 1; - while (rep1 < length && string[rep1] == string[i]) - { - ++rep1; - ++reps; - } - - if (reps > repeat_count_threshold) - { - if (in_quotes) - { - if (inspect_it) - fputs_filtered ("\\\", ", stream); - else - fputs_filtered ("\", ", stream); - in_quotes = 0; - } - m2_printchar (string[i], stream); - fprintf_filtered (stream, " ", reps); - i = rep1 - 1; - things_printed += repeat_count_threshold; - need_comma = 1; - } - else - { - if (!in_quotes) - { - if (inspect_it) - fputs_filtered ("\\\"", stream); - else - fputs_filtered ("\"", stream); - in_quotes = 1; - } - emit_char (string[i], stream, '"'); - ++things_printed; - } - } - - /* Terminate the quotes if necessary. */ - if (in_quotes) - { - if (inspect_it) - fputs_filtered ("\\\"", stream); - else - fputs_filtered ("\"", stream); - } - - if (force_ellipses || i < length) - fputs_filtered ("...", stream); -} - -/* FIXME: This is a copy of c_create_fundamental_type(), before - all the non-C types were stripped from it. Needs to be fixed - by an experienced Modula programmer. */ - -static struct type * -m2_create_fundamental_type (objfile, typeid) - struct objfile *objfile; - int typeid; -{ - register struct type *type = NULL; - - switch (typeid) - { - default: - /* FIXME: For now, if we are asked to produce a type not in this - language, create the equivalent of a C integer type with the - name "". When all the dust settles from the type - reconstruction work, this should probably become an error. */ - type = init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "", objfile); - warning ("internal error: no Modula fundamental type %d", typeid); - break; - case FT_VOID: - type = init_type (TYPE_CODE_VOID, - 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, - TYPE_FLAG_UNSIGNED, "boolean", objfile); - break; - case FT_STRING: - type = init_type (TYPE_CODE_STRING, - TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, "string", objfile); - break; - case FT_CHAR: - type = init_type (TYPE_CODE_INT, - TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, "char", objfile); - break; - case FT_SIGNED_CHAR: - type = init_type (TYPE_CODE_INT, - TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, "signed char", objfile); - break; - case FT_UNSIGNED_CHAR: - type = init_type (TYPE_CODE_INT, - TARGET_CHAR_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned char", objfile); - break; - case FT_SHORT: - type = init_type (TYPE_CODE_INT, - TARGET_SHORT_BIT / TARGET_CHAR_BIT, - 0, "short", objfile); - break; - case FT_SIGNED_SHORT: - type = init_type (TYPE_CODE_INT, - TARGET_SHORT_BIT / TARGET_CHAR_BIT, - 0, "short", objfile); /* FIXME-fnf */ - break; - case FT_UNSIGNED_SHORT: - type = init_type (TYPE_CODE_INT, - TARGET_SHORT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned short", objfile); - break; - case FT_INTEGER: - type = init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "int", objfile); - break; - case FT_SIGNED_INTEGER: - type = init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "int", objfile); /* FIXME -fnf */ - break; - case FT_UNSIGNED_INTEGER: - type = init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned int", objfile); - break; - case FT_FIXED_DECIMAL: - type = init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "fixed decimal", objfile); - break; - case FT_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_BIT / TARGET_CHAR_BIT, - 0, "long", objfile); - break; - case FT_SIGNED_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_BIT / TARGET_CHAR_BIT, - 0, "long", objfile); /* FIXME -fnf */ - break; - case FT_UNSIGNED_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned long", objfile); - break; - case FT_LONG_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, - 0, "long long", objfile); - break; - case FT_SIGNED_LONG_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, - 0, "signed long long", objfile); - break; - case FT_UNSIGNED_LONG_LONG: - type = init_type (TYPE_CODE_INT, - TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned long long", objfile); - break; - case FT_FLOAT: - type = init_type (TYPE_CODE_FLT, - TARGET_FLOAT_BIT / TARGET_CHAR_BIT, - 0, "float", objfile); - break; - case FT_DBL_PREC_FLOAT: - type = init_type (TYPE_CODE_FLT, - TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, - 0, "double", objfile); - break; - case FT_FLOAT_DECIMAL: - type = init_type (TYPE_CODE_FLT, - TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, - 0, "floating decimal", objfile); - break; - case FT_EXT_PREC_FLOAT: - type = init_type (TYPE_CODE_FLT, - TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT, - 0, "long double", objfile); - break; - case FT_COMPLEX: - type = init_type (TYPE_CODE_FLT, - TARGET_COMPLEX_BIT / TARGET_CHAR_BIT, - 0, "complex", objfile); - break; - case FT_DBL_PREC_COMPLEX: - type = init_type (TYPE_CODE_FLT, - TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT, - 0, "double complex", objfile); - break; - case FT_EXT_PREC_COMPLEX: - type = init_type (TYPE_CODE_FLT, - TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT, - 0, "long double complex", objfile); - break; - } - return (type); -} - - -/* Table of operators and their precedences for printing expressions. */ - -static const struct op_print m2_op_print_tab[] = { - {"+", BINOP_ADD, PREC_ADD, 0}, - {"+", UNOP_PLUS, PREC_PREFIX, 0}, - {"-", BINOP_SUB, PREC_ADD, 0}, - {"-", UNOP_NEG, PREC_PREFIX, 0}, - {"*", BINOP_MUL, PREC_MUL, 0}, - {"/", BINOP_DIV, PREC_MUL, 0}, - {"DIV", BINOP_INTDIV, PREC_MUL, 0}, - {"MOD", BINOP_REM, PREC_MUL, 0}, - {":=", BINOP_ASSIGN, PREC_ASSIGN, 1}, - {"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0}, - {"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0}, - {"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 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}, - {"^", UNOP_IND, PREC_PREFIX, 0}, - {"@", BINOP_REPEAT, PREC_REPEAT, 0}, - {NULL, 0, 0, 0} -}; - -/* The built-in types of Modula-2. */ - -struct type *builtin_type_m2_char; -struct type *builtin_type_m2_int; -struct type *builtin_type_m2_card; -struct type *builtin_type_m2_real; -struct type *builtin_type_m2_bool; - -struct type ** const (m2_builtin_types[]) = -{ - &builtin_type_m2_char, - &builtin_type_m2_int, - &builtin_type_m2_card, - &builtin_type_m2_real, - &builtin_type_m2_bool, - 0 -}; - -const struct language_defn m2_language_defn = { - "modula-2", - language_m2, - m2_builtin_types, - range_check_on, - type_check_on, - m2_parse, /* parser */ - m2_error, /* parser error function */ - m2_printchar, /* Print character constant */ - m2_printstr, /* function to print string constant */ - 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 */ - c_value_print, /* Print a top-level value */ - &builtin_type_m2_real, /* longest floating point type */ - {"", "", "", ""}, /* Binary format info */ - {"%loB", "", "o", "B"}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0%lXH", "0", "X", "H"}, /* Hex format info */ - m2_op_print_tab, /* expression operators for printing */ - LANG_MAGIC -}; - -/* Initialization for Modula-2 */ - -void -_initialize_m2_language () -{ - /* Modula-2 "pervasive" types. NOTE: these can be redefined!!! */ - builtin_type_m2_int = - init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, - "INTEGER", (struct objfile *) NULL); - builtin_type_m2_card = - init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "CARDINAL", (struct objfile *) NULL); - builtin_type_m2_real = - init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT, - 0, - "REAL", (struct objfile *) NULL); - builtin_type_m2_char = - init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "CHAR", (struct objfile *) NULL); - builtin_type_m2_bool = - init_type (TYPE_CODE_BOOL, TARGET_INT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, - "BOOLEAN", (struct objfile *) NULL); - - add_language (&m2_language_defn); -} diff --git a/gnu/usr.bin/gdb/gdb/m2-lang.h b/gnu/usr.bin/gdb/gdb/m2-lang.h deleted file mode 100644 index 38f4687..0000000 --- a/gnu/usr.bin/gdb/gdb/m2-lang.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Modula 2 language support definitions for GDB, the GNU debugger. - Copyright 1992 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. */ - -extern int -m2_parse PARAMS ((void)); /* Defined in m2-exp.y */ - -extern void -m2_error PARAMS ((char *)); /* Defined in m2-exp.y */ - -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, - int, enum val_prettyprint)); diff --git a/gnu/usr.bin/gdb/gdb/m2-typeprint.c b/gnu/usr.bin/gdb/gdb/m2-typeprint.c deleted file mode 100644 index c9ee800..0000000 --- a/gnu/usr.bin/gdb/gdb/m2-typeprint.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Support for printing Modula 2 types for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991 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 "defs.h" -#include "obstack.h" -#include "bfd.h" /* Binary File Description */ -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "value.h" -#include "gdbcore.h" -#include "target.h" -#include "command.h" -#include "gdbcmd.h" -#include "language.h" -#include "demangle.h" -#include "m2-lang.h" - -#include -#include - -void -m2_print_type (type, varstring, stream, show, level) - struct type *type; - char *varstring; - GDB_FILE *stream; - int show; - int level; -{ - extern void c_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int)); - - c_print_type (type, varstring, stream, show, level); /* FIXME */ -} diff --git a/gnu/usr.bin/gdb/gdb/m2-valprint.c b/gnu/usr.bin/gdb/gdb/m2-valprint.c deleted file mode 100644 index 4a314b9..0000000 --- a/gnu/usr.bin/gdb/gdb/m2-valprint.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Support for printing Modula 2 values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991 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 "defs.h" -#include "obstack.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "valprint.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) - struct type *type; - char *valaddr; - CORE_ADDR address; - GDB_FILE *stream; - int format; - int deref_ref; - int 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, - recurse, pretty)); -} diff --git a/gnu/usr.bin/gdb/gdb/main.c b/gnu/usr.bin/gdb/gdb/main.c deleted file mode 100644 index cd434e5..0000000 --- a/gnu/usr.bin/gdb/gdb/main.c +++ /dev/null @@ -1,571 +0,0 @@ -/* Top level stuff for GDB, the GNU debugger. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 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. */ - -#include "defs.h" -#include -#include "top.h" -#include "target.h" -#include "inferior.h" -#include "call-cmds.h" - -#include "getopt.h" - -#include -#include -#include - -#include -/* R_OK lives in either unistd.h or sys/file.h. */ -#ifdef USG -#include -#endif -#ifndef NO_SYS_FILE -#include -#endif - -/* Temporary variable for SET_TOP_LEVEL. */ -static int top_level_val; - -/* Do a setjmp on error_return and quit_return. catch_errors is - generally a cleaner way to do this, but main() would look pretty - 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) - -extern void gdb_init PARAMS ((void)); - -int -main (argc, argv) - int argc; - char **argv; -{ - int count; - static int quiet = 0; - static int batch = 0; - - /* Pointers to various arguments from command line. */ - char *symarg = NULL; - char *execarg = NULL; - char *corearg = NULL; - char *cdarg = NULL; - char *ttyarg = NULL; - - /* These are static so that we can take their address in an initializer. */ - static int print_help; - static int print_version; - - /* Pointers to all arguments of --command option. */ - char **cmdarg; - /* Allocated size of cmdarg. */ - int cmdsize; - /* Number of elements of cmdarg used. */ - int ncmd; - - /* Indices of all arguments of --directory option. */ - char **dirarg; - /* Allocated size. */ - int dirsize; - /* Number of elements used. */ - int ndir; - - struct stat homebuf, cwdbuf; - char *homedir, *homeinit; - - register int i; - - /* This needs to happen before the first use of malloc. */ - init_malloc ((PTR) NULL); - -#if defined (ALIGN_STACK_ON_STARTUP) - i = (int) &count & 0x3; - if (i != 0) - alloca (4 - i); -#endif - - /* If error() is called from initialization code, just exit */ - if (SET_TOP_LEVEL ()) { - exit(1); - } - - cmdsize = 1; - cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg)); - ncmd = 0; - dirsize = 1; - dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg)); - ndir = 0; - - quit_flag = 0; - line = (char *) xmalloc (linesize); - line[0] = '\0'; /* Terminate saved (now empty) cmd line */ - instream = stdin; - - getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); - current_directory = gdb_dirbuf; - -#ifdef KERNEL_DEBUG - if (strstr(argv[0], "kgdb") != NULL) - kernel_debugging = 1; -#endif - - /* Parse arguments and options. */ - { - int c; - /* When var field is 0, use flag field to record the equivalent - short option (or arbitrary numbers starting at 10 for those - with no equivalent). */ - static struct option long_options[] = - { - {"readnow", no_argument, &readnow_symbol_files, 1}, - {"r", no_argument, &readnow_symbol_files, 1}, - {"mapped", no_argument, &mapped_symbol_files, 1}, - {"m", no_argument, &mapped_symbol_files, 1}, - {"quiet", no_argument, &quiet, 1}, - {"q", no_argument, &quiet, 1}, - {"silent", no_argument, &quiet, 1}, - {"nx", no_argument, &inhibit_gdbinit, 1}, - {"n", no_argument, &inhibit_gdbinit, 1}, - {"batch", no_argument, &batch, 1}, - {"epoch", no_argument, &epoch_interface, 1}, - - /* This is a synonym for "--annotate=1". --annotate is now preferred, - but keep this here for a long time because people will be running - emacses which use --fullname. */ - {"fullname", no_argument, 0, 'f'}, - {"f", no_argument, 0, 'f'}, - - {"annotate", required_argument, 0, 12}, - {"help", no_argument, &print_help, 1}, - {"se", required_argument, 0, 10}, - {"symbols", required_argument, 0, 's'}, - {"s", required_argument, 0, 's'}, - {"exec", required_argument, 0, 'e'}, - {"e", required_argument, 0, 'e'}, - {"core", required_argument, 0, 'c'}, - {"c", required_argument, 0, 'c'}, - {"command", required_argument, 0, 'x'}, - {"version", no_argument, &print_version, 1}, - {"x", required_argument, 0, 'x'}, - {"directory", required_argument, 0, 'd'}, - {"cd", required_argument, 0, 11}, - {"tty", required_argument, 0, 't'}, - {"baud", required_argument, 0, 'b'}, - {"b", required_argument, 0, 'b'}, -#ifdef KERNEL_DEBUG - {"kernel", no_argument, &kernel_debugging, 1}, - {"k", no_argument, &kernel_debugging, 1}, - {"wcore", no_argument, &kernel_writablecore, 1}, - {"w", no_argument, &kernel_writablecore, 1}, -#endif -/* Allow machine descriptions to add more options... */ -#ifdef ADDITIONAL_OPTIONS - ADDITIONAL_OPTIONS -#endif - {0, no_argument, 0, 0}, - }; - - while (1) - { - int option_index; - - c = getopt_long_only (argc, argv, "", - long_options, &option_index); - if (c == EOF) - break; - - /* Long option that takes an argument. */ - if (c == 0 && long_options[option_index].flag == 0) - c = long_options[option_index].val; - - switch (c) - { - case 0: - /* Long option that just sets a flag. */ - break; - case 10: - symarg = optarg; - execarg = optarg; - break; - case 11: - cdarg = optarg; - break; - case 12: - /* FIXME: what if the syntax is wrong (e.g. not digits)? */ - annotation_level = atoi (optarg); - break; - case 'f': - annotation_level = 1; - break; - case 's': - symarg = optarg; - break; - case 'e': - execarg = optarg; - break; - case 'c': - corearg = optarg; - break; - case 'x': - cmdarg[ncmd++] = optarg; - if (ncmd >= cmdsize) - { - cmdsize *= 2; - cmdarg = (char **) xrealloc ((char *)cmdarg, - cmdsize * sizeof (*cmdarg)); - } - break; - case 'd': - dirarg[ndir++] = optarg; - if (ndir >= dirsize) - { - dirsize *= 2; - dirarg = (char **) xrealloc ((char *)dirarg, - dirsize * sizeof (*dirarg)); - } - break; - case 't': - ttyarg = optarg; - break; - case 'q': - quiet = 1; - break; - case 'b': - { - 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 baud rate to `%s'.\n", optarg); - else - baud_rate = i; - } - break; -#ifdef KERNEL_DEBUG - case 'k': - kernel_debugging = 1; - break; - case 'w': - kernel_writablecore = 1; - break; -#endif - -#ifdef ADDITIONAL_OPTION_CASES - ADDITIONAL_OPTION_CASES -#endif - case '?': - fprintf_unfiltered (gdb_stderr, - "Use `%s --help' for a complete list of options.\n", - argv[0]); - exit (1); - } - } - - /* OK, that's all the options. The other arguments are filenames. */ - count = 0; - for (; optind < argc; optind++) - switch (++count) - { - case 1: - symarg = argv[optind]; - execarg = argv[optind]; - break; - case 2: - corearg = argv[optind]; - break; - case 3: - fprintf_unfiltered (gdb_stderr, - "Excess command line arguments ignored. (%s%s)\n", - argv[optind], (optind == argc - 1) ? "" : " ..."); - break; - } - if (batch) - quiet = 1; - } - - gdb_init (); - - /* Do these (and anything which might call wrap_here or *_filtered) - after initialize_all_files. */ - if (print_version) - { - print_gdb_version (gdb_stdout); - wrap_here (""); - printf_filtered ("\n"); - exit (0); - } - - 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\ - --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\ - --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\ - --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\ -", gdb_stdout); -#ifdef KERNEL_DEBUG - fputs_unfiltered ("\ - --kernel Enable kernel debugging.\n\ - --wcore Make core file writable (only works for /dev/mem).\n\ - This option only works while debugging a kernel !!\n\ -", gdb_stdout); -#endif /* KERNEL_DEBUGGING */ -#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); - exit (0); - } - - if (!quiet) - { - /* 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 (".."); - wrap_here(""); - gdb_flush (gdb_stdout); /* Force to screen during slow operations */ - } - - error_pre_print = "\n\n"; - /* We may get more than one warning, don't double space all of them... */ - warning_pre_print = "\nwarning: "; - - /* Read and execute $HOME/.gdbinit file, if it exists. This is done - *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"); - if (homedir) - { - homeinit = (char *) alloca (strlen (getenv ("HOME")) + - strlen (gdbinit) + 10); - strcpy (homeinit, getenv ("HOME")); - strcat (homeinit, "/"); - strcat (homeinit, gdbinit); - if (!inhibit_gdbinit && access (homeinit, R_OK) == 0) - { - if (!SET_TOP_LEVEL ()) - source_command (homeinit, 0); - } - do_cleanups (ALL_CLEANUPS); - - /* Do stats; no need to do them elsewhere since we'll only - need them if homedir is set. Make sure that they are - zero in case one of them fails (this guarantees that they - won't match if either exists). */ - - memset (&homebuf, 0, sizeof (struct stat)); - memset (&cwdbuf, 0, sizeof (struct stat)); - - stat (homeinit, &homebuf); - stat (gdbinit, &cwdbuf); /* We'll only need this if - homedir was set. */ - } - - /* Now perform all the actions indicated by the arguments. */ - if (cdarg != NULL) - { - if (!SET_TOP_LEVEL ()) - { - cd_command (cdarg, 0); - } - } - do_cleanups (ALL_CLEANUPS); - - for (i = 0; i < ndir; i++) - if (!SET_TOP_LEVEL ()) - directory_command (dirarg[i], 0); - free ((PTR)dirarg); - do_cleanups (ALL_CLEANUPS); - - if (execarg != NULL - && symarg != NULL - && STREQ (execarg, symarg)) - { - /* The exec file and the symbol-file are the same. If we can't open - it, better only print one error message. */ - if (!SET_TOP_LEVEL ()) - { - exec_file_command (execarg, !batch); - symbol_file_command (symarg, 0); - } - } - else - { - if (execarg != NULL) - if (!SET_TOP_LEVEL ()) - exec_file_command (execarg, !batch); - if (symarg != NULL) - if (!SET_TOP_LEVEL ()) - symbol_file_command (symarg, 0); - } - do_cleanups (ALL_CLEANUPS); - - /* After the symbol file has been read, print a newline to get us - beyond the copyright line... But errors should still set off - the error message with a (single) blank line. */ - if (!quiet) - printf_filtered ("\n"); - error_pre_print = "\n"; - 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); - do_cleanups (ALL_CLEANUPS); - - if (ttyarg != NULL) - if (!SET_TOP_LEVEL ()) - tty_command (ttyarg, !batch); - do_cleanups (ALL_CLEANUPS); - -#ifdef ADDITIONAL_OPTION_HANDLER - ADDITIONAL_OPTION_HANDLER; -#endif - - /* Error messages should no longer be distinguished with extra output. */ - error_pre_print = 0; - warning_pre_print = "warning: "; - - /* Read the .gdbinit file in the current directory, *if* it isn't - the same as the $HOME/.gdbinit file (it should exist, also). */ - - if (!homedir - || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat))) - if (!inhibit_gdbinit && access (gdbinit, R_OK) == 0) - { - if (!SET_TOP_LEVEL ()) - source_command (gdbinit, 0); - } - do_cleanups (ALL_CLEANUPS); - - for (i = 0; i < ncmd; i++) - { - if (!SET_TOP_LEVEL ()) - { - if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0') - read_command_file (stdin); - else - source_command (cmdarg[i], !batch); - do_cleanups (ALL_CLEANUPS); - } - } - free ((PTR)cmdarg); - - /* Read in the old history after all the command files have been read. */ - init_history(); - - if (batch) - { - /* We have hit the end of the batch file. */ - exit (0); - } - - /* Do any host- or target-specific hacks. This is used for i960 targets - to force the user to set a nindy target and spec its parameters. */ - -#ifdef BEFORE_MAIN_LOOP_HOOK - BEFORE_MAIN_LOOP_HOOK; -#endif - - /* The command loop. */ - - while (1) - { - if (!SET_TOP_LEVEL ()) - { - do_cleanups (ALL_CLEANUPS); /* Do complete cleanup */ - command_loop (); - quit_command ((char *)0, instream == stdin); - } - } - /* No exit -- exit is through quit_command. */ -} - -void -init_proc () -{ -} - -int -proc_wait (pid, status) - int pid; - int *status; -{ -#ifndef __GO32__ - return wait (status); -#endif -} - -void -proc_remove_foreign (pid) - int pid; -{ -} - -void -fputs_unfiltered (linebuffer, stream) - const char *linebuffer; - FILE *stream; -{ - fputs (linebuffer, stream); -} diff --git a/gnu/usr.bin/gdb/gdb/maint.c b/gnu/usr.bin/gdb/gdb/maint.c deleted file mode 100644 index ce39506..0000000 --- a/gnu/usr.bin/gdb/gdb/maint.c +++ /dev/null @@ -1,295 +0,0 @@ -/* Support for GDB maintenance commands. - Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Fred Fish at 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include "defs.h" - -#if MAINTENANCE_CMDS /* Entire file goes away if not including maint cmds */ - -#include -#include "command.h" -#include "gdbcmd.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "demangle.h" -#include "gdbcore.h" -#include "expression.h" /* For language.h */ -#include "language.h" - -static void -maintenance_command PARAMS ((char *, int)); - -static void -maintenance_dump_me PARAMS ((char *, int)); - -static void -maintenance_demangle PARAMS ((char *, int)); - -/* - -LOCAL FUNCTION - - maintenance_command -- access the maintenance subcommands - -SYNOPSIS - - void maintenance_command (char *args, int from_tty) - -DESCRIPTION - -*/ - -static void -maintenance_command (args, from_tty) - char *args; - int from_tty; -{ - printf_unfiltered ("\"maintenance\" must be followed by the name of a maintenance command.\n"); - help_list (maintenancelist, "maintenance ", -1, gdb_stdout); -} - - -/* ARGSUSED */ -static void -maintenance_dump_me (args, from_tty) - char *args; - int from_tty; -{ - if (query ("Should GDB dump core? ")) - { - signal (SIGQUIT, SIG_DFL); - kill (getpid (), SIGQUIT); - } -} - -/* Someday we should allow demangling for things other than just - explicit strings. For example, we might want to be able to - specify the address of a string in either GDB's process space - or the debuggee's process space, and have gdb fetch and demangle - that string. If we have a char* pointer "ptr" that points to - a string, we might want to be able to given just the name and - have GDB demangle and print what it points to, etc. (FIXME) */ - -static void -maintenance_demangle (args, from_tty) - char *args; - int from_tty; -{ - char *demangled; - - if (args == NULL || *args == '\0') - { - printf_unfiltered ("\"maintenance demangle\" takes an argument to demangle.\n"); - } - else - { - demangled = cplus_demangle (args, DMGL_ANSI | DMGL_PARAMS); - if (demangled != NULL) - { - printf_unfiltered ("%s\n", demangled); - free (demangled); - } - else - { - printf_unfiltered ("Can't demangle \"%s\"\n", args); - } - } -} - -/* The "maintenance info" command is defined as a prefix, with allow_unknown 0. - Therefore, its own definition is called only for "maintenance info" with - no args. */ - -/* ARGSUSED */ -static void -maintenance_info_command (arg, from_tty) - char *arg; - int from_tty; -{ - printf_unfiltered ("\"maintenance info\" must be followed by the name of an info command.\n"); - help_list (maintenanceinfolist, "maintenance info ", -1, gdb_stdout); -} - -static void -print_section_table (abfd, asect, ignore) - bfd *abfd; - asection *asect; - PTR ignore; -{ - flagword flags; - - flags = bfd_get_section_flags (abfd, asect); - - /* FIXME-32x64: Need print_address_numeric with field width. */ - printf_filtered (" %s", - local_hex_string_custom - ((unsigned long) bfd_section_vma (abfd, asect), "08l")); - printf_filtered ("->%s", - local_hex_string_custom - ((unsigned long) (bfd_section_vma (abfd, asect) - + bfd_section_size (abfd, asect)), - "08l")); - printf_filtered (" at %s", - local_hex_string_custom - ((unsigned long) asect->filepos, "08l")); - printf_filtered (": %s", bfd_section_name (abfd, asect)); - - if (flags & SEC_ALLOC) - printf_filtered (" ALLOC"); - if (flags & SEC_LOAD) - printf_filtered (" LOAD"); - if (flags & SEC_RELOC) - printf_filtered (" RELOC"); - if (flags & SEC_READONLY) - printf_filtered (" READONLY"); - if (flags & SEC_CODE) - printf_filtered (" CODE"); - if (flags & SEC_DATA) - printf_filtered (" DATA"); - if (flags & SEC_ROM) - printf_filtered (" ROM"); - if (flags & SEC_CONSTRUCTOR) - printf_filtered (" CONSTRUCTOR"); - if (flags & SEC_HAS_CONTENTS) - printf_filtered (" HAS_CONTENTS"); - if (flags & SEC_NEVER_LOAD) - printf_filtered (" NEVER_LOAD"); - if (flags & SEC_COFF_SHARED_LIBRARY) - printf_filtered (" COFF_SHARED_LIBRARY"); - if (flags & SEC_IS_COMMON) - printf_filtered (" IS_COMMON"); - - printf_filtered ("\n"); -} - -/* ARGSUSED */ -static void -maintenance_info_sections (arg, from_tty) - char *arg; - int from_tty; -{ - if (exec_bfd) - { - printf_filtered ("Exec file:\n"); - printf_filtered (" `%s', ", bfd_get_filename(exec_bfd)); - wrap_here (" "); - printf_filtered ("file type %s.\n", bfd_get_target(exec_bfd)); - bfd_map_over_sections(exec_bfd, print_section_table, 0); - } - - if (core_bfd) - { - printf_filtered ("Core file:\n"); - printf_filtered (" `%s', ", bfd_get_filename(core_bfd)); - wrap_here (" "); - printf_filtered ("file type %s.\n", bfd_get_target(core_bfd)); - bfd_map_over_sections(core_bfd, print_section_table, 0); - } -} - -/* The "maintenance print" command is defined as a prefix, with allow_unknown - 0. Therefore, its own definition is called only for "maintenance print" - with no args. */ - -/* ARGSUSED */ -static void -maintenance_print_command (arg, from_tty) - char *arg; - int from_tty; -{ - printf_unfiltered ("\"maintenance print\" must be followed by the name of a print command.\n"); - help_list (maintenanceprintlist, "maintenance print ", -1, gdb_stdout); -} - -#endif /* MAINTENANCE_CMDS */ - -void -_initialize_maint_cmds () -{ -#if MAINTENANCE_CMDS /* Entire file goes away if not including maint cmds */ - add_prefix_cmd ("maintenance", class_maintenance, maintenance_command, - "Commands for use by GDB maintainers.\n\ -Includes commands to dump specific internal GDB structures in\n\ -a human readable form, to cause GDB to deliberately dump core,\n\ -to test internal functions such as the C++ demangler, etc.", - &maintenancelist, "maintenance ", 0, - &cmdlist); - - add_com_alias ("mt", "maintenance", class_maintenance, 1); - - add_prefix_cmd ("info", class_maintenance, maintenance_info_command, - "Commands for showing internal info about the program being debugged.", - &maintenanceinfolist, "maintenance info ", 0, - &maintenancelist); - - add_cmd ("sections", class_maintenance, maintenance_info_sections, - "List the BFD sections of the exec and core files.", - &maintenanceinfolist); - - add_prefix_cmd ("print", class_maintenance, maintenance_print_command, - "Maintenance command for printing GDB internal state.", - &maintenanceprintlist, "maintenance print ", 0, - &maintenancelist); - - 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); - - add_cmd ("demangle", class_maintenance, maintenance_demangle, - "Demangle a C++ mangled name.\n\ -Call internal GDB demangler routine to demangle a C++ link name\n\ -and prints the result.", - &maintenancelist); - - add_cmd ("type", class_maintenance, maintenance_print_type, - "Print a type chain for a given symbol.\n\ -For each node in a type chain, print the raw data for each member of\n\ -the type structure, and the interpretation of the data.", - &maintenanceprintlist); - - add_cmd ("symbols", class_maintenance, maintenance_print_symbols, - "Print dump of current symbol definitions.\n\ -Entries in the full symbol table are dumped to file OUTFILE.\n\ -If a SOURCE file is specified, dump only that file's symbols.", - &maintenanceprintlist); - - add_cmd ("msymbols", class_maintenance, maintenance_print_msymbols, - "Print dump of current minimal symbol definitions.\n\ -Entries in the minimal symbol table are dumped to file OUTFILE.\n\ -If a SOURCE file is specified, dump only that file's minimal symbols.", - &maintenanceprintlist); - - add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, - "Print dump of current partial symbol definitions.\n\ -Entries in the partial symbol table are dumped to file OUTFILE.\n\ -If a SOURCE file is specified, dump only that file's partial symbols.", - &maintenanceprintlist); - - add_cmd ("objfiles", class_maintenance, maintenance_print_objfiles, - "Print dump of current object file definitions.", - &maintenanceprintlist); - - add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs, - "Check consistency of psymtabs and symtabs.", - &maintenancelist); -#endif /* MAINTENANCE_CMDS */ -} diff --git a/gnu/usr.bin/gdb/gdb/mdebugread.c b/gnu/usr.bin/gdb/gdb/mdebugread.c deleted file mode 100644 index 9c1309f..0000000 --- a/gnu/usr.bin/gdb/gdb/mdebugread.c +++ /dev/null @@ -1,4053 +0,0 @@ -/* Read a symbol table in ECOFF format (Third-Eye). - Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994 - 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 - at 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* This module provides the function mdebug_build_psymtabs. It reads - ECOFF debugging information into partial symbol tables. The - debugging information is read from two structures. A struct - ecoff_debug_swap includes the sizes of each ECOFF structure and - swapping routines; these are fixed for a particular target. A - struct ecoff_debug_info points to the debugging information for a - particular object file. - - ECOFF symbol tables are mostly written in the byte order of the - target machine. However, one section of the table (the auxiliary - symbol information) is written in the host byte order. There is a - bit in the other symbol info which describes which host byte order - was used. ECOFF thereby takes the trophy from Intel `b.out' for - the most brain-dead adaptation of a file format to byte order. - - This module can read all four of the known byte-order combinations, - on any type of host. */ - -#include "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "gdbcore.h" -#include "symfile.h" -#include "objfiles.h" -#include "obstack.h" -#include "buildsym.h" -#include "stabsread.h" -#include "complaints.h" - -#if !defined (SEEK_SET) -#define SEEK_SET 0 -#define SEEK_CUR 1 -#endif - -/* These are needed if the tm.h file does not contain the necessary - mips specific definitions. */ - -#ifndef MIPS_EFI_SYMBOL_NAME -#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__" -#include "coff/sym.h" -#include "coff/symconst.h" -typedef struct mips_extra_func_info { - long numargs; - PDR pdr; -} *mips_extra_func_info_t; -#ifndef RA_REGNUM -#define RA_REGNUM 0 -#endif -#endif - -#ifdef USG -#include -#endif - -#include -#include -#include -#include - -#include "gdb-stabs.h" - -#include "bfd.h" - -#include "coff/ecoff.h" /* COFF-like aspects of ecoff files */ - -#include "libaout.h" /* Private BFD a.out information. */ -#include "aout/aout64.h" -#include "aout/stab_gnu.h" /* STABS information */ - -#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 - -/* Each partial symbol table entry contains a pointer to private data - for the read_symtab() function to use when expanding a partial - symbol table entry to a full symbol table entry. - - For mdebugread this structure contains the index of the FDR that this - psymtab represents and a pointer to the BFD that the psymtab was - created from. */ - -#define PST_PRIVATE(p) ((struct symloc *)(p)->read_symtab_private) -#define FDR_IDX(p) (PST_PRIVATE(p)->fdr_idx) -#define CUR_BFD(p) (PST_PRIVATE(p)->cur_bfd) -#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) - -struct symloc -{ - int fdr_idx; - bfd *cur_bfd; - const struct ecoff_debug_swap *debug_swap; - struct ecoff_debug_info *debug_info; - struct mdebug_pending **pending_list; - EXTR *extern_tab; /* Pointer to external symbols for this file. */ - int extern_count; /* Size of extern_tab. */ - enum language pst_language; -}; - -/* Things we import explicitly from other modules */ - -extern int info_verbose; - -/* Various complaints about symbol reading that don't abort the process */ - -static struct complaint bad_file_number_complaint = -{"bad file number %d", 0, 0}; - -static struct complaint index_complaint = -{"bad aux index at symbol %s", 0, 0}; - -static struct complaint aux_index_complaint = -{"bad proc end in aux found from symbol %s", 0, 0}; - -static struct complaint block_index_complaint = -{"bad aux index at block symbol %s", 0, 0}; - -static struct complaint unknown_ext_complaint = -{"unknown external symbol %s", 0, 0}; - -static struct complaint unknown_sym_complaint = -{"unknown local symbol %s", 0, 0}; - -static struct complaint unknown_st_complaint = -{"with type %d", 0, 0}; - -static struct complaint block_overflow_complaint = -{"block containing %s overfilled", 0, 0}; - -static struct complaint basic_type_complaint = -{"cannot map ECOFF basic type 0x%x for %s", 0, 0}; - -static struct complaint unknown_type_qual_complaint = -{"unknown type qualifier 0x%x", 0, 0}; - -static struct complaint array_index_type_complaint = -{"illegal array index type for %s, assuming int", 0, 0}; - -static struct complaint bad_tag_guess_complaint = -{"guessed tag type of %s incorrectly", 0, 0}; - -static struct complaint block_member_complaint = -{"declaration block contains unhandled symbol type %d", 0, 0}; - -static struct complaint stEnd_complaint = -{"stEnd with storage class %d not handled", 0, 0}; - -static struct complaint unknown_mdebug_symtype_complaint = -{"unknown symbol type 0x%x", 0, 0}; - -static struct complaint stab_unknown_complaint = -{"unknown stabs symbol %s", 0, 0}; - -static struct complaint pdr_for_nonsymbol_complaint = -{"PDR for %s, but no symbol", 0, 0}; - -static struct complaint pdr_static_symbol_complaint = -{"can't handle PDR for static proc at 0x%lx", 0, 0}; - -static struct complaint bad_setjmp_pdr_complaint = -{"fixing bad setjmp PDR from libc", 0, 0}; - -static struct complaint bad_fbitfield_complaint = -{"can't handle TIR fBitfield for %s", 0, 0}; - -static struct complaint bad_continued_complaint = -{"illegal TIR continued for %s", 0, 0}; - -static struct complaint bad_rfd_entry_complaint = -{"bad rfd entry for %s: file %d, index %d", 0, 0}; - -static struct complaint unexpected_type_code_complaint = -{"unexpected type code for %s", 0, 0}; - -static struct complaint unable_to_cross_ref_complaint = -{"unable to cross ref btTypedef for %s", 0, 0}; - -static struct complaint illegal_forward_tq0_complaint = -{"illegal tq0 in forward typedef for %s", 0, 0}; - -static struct complaint illegal_forward_bt_complaint = -{"illegal bt %d in forward typedef for %s", 0, 0}; - -static struct complaint bad_linetable_guess_complaint = -{"guessed size of linetable for %s incorrectly", 0, 0}; - -static struct complaint bad_ext_ifd_complaint = -{"bad ifd for external symbol: %d (max %d)", 0, 0}; - -static struct complaint bad_ext_iss_complaint = -{"bad iss for external symbol: %ld (max %ld)", 0, 0}; - -/* Macros and extra defs */ - -/* Puns: hard to find whether -g was used and how */ - -#define MIN_GLEVEL GLEVEL_0 -#define compare_glevel(a,b) \ - (((a) == GLEVEL_3) ? ((b) < GLEVEL_3) : \ - ((b) == GLEVEL_3) ? -1 : (int)((b) - (a))) - -/* Things that really are local to this module */ - -/* Remember what we deduced to be the source language of this psymtab. */ - -static enum language psymtab_language = language_unknown; - -/* Current BFD. */ - -static bfd *cur_bfd; - -/* How to parse debugging information for CUR_BFD. */ - -static const struct ecoff_debug_swap *debug_swap; - -/* Pointers to debugging information for CUR_BFD. */ - -static struct ecoff_debug_info *debug_info; - -/* Pointer to current file decriptor record, and its index */ - -static FDR *cur_fdr; -static int cur_fd; - -/* Index of current symbol */ - -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; - -/* When examining .o files, report on undefined symbols */ - -static int n_undef_symbols, n_undef_labels, n_undef_vars, n_undef_procs; - -/* Pseudo symbol to use when putting stabs into the symbol table. */ - -static char stabs_symbol[] = STABS_SYMBOL; - -/* Types corresponding to btComplex, btDComplex, etc. These are here - rather than in gdbtypes.c or some such, because the meaning of codes - like btComplex is specific to the mdebug debug format. FIXME: We should - be using our own types thoughout this file, instead of sometimes using - builtin_type_*. */ - -static struct type *mdebug_type_complex; -static struct type *mdebug_type_double_complex; -static struct type *mdebug_type_fixed_dec; -static struct type *mdebug_type_float_dec; -static struct type *mdebug_type_string; - -/* Forward declarations */ - -static int -upgrade_type PARAMS ((int, struct type **, int, union aux_ext *, int, char *)); - -static void -parse_partial_symbols PARAMS ((struct objfile *, - struct section_offsets *)); - -static FDR -*get_rfd PARAMS ((int, int)); - -static int -has_opaque_xref PARAMS ((FDR *, SYMR *)); - -static int -cross_ref PARAMS ((int, union aux_ext *, struct type **, enum type_code, - char **, int, char *)); - -static struct symbol * -new_symbol PARAMS ((char *)); - -static struct type * -new_type PARAMS ((char *)); - -static struct block * -new_block PARAMS ((int)); - -static struct symtab * -new_symtab PARAMS ((char *, int, int, struct objfile *)); - -static struct linetable * -new_linetable PARAMS ((int)); - -static struct blockvector * -new_bvect PARAMS ((int)); - -static int -parse_symbol PARAMS ((SYMR *, union aux_ext *, char *, int, struct section_offsets *)); - -static struct type * -parse_type PARAMS ((int, union aux_ext *, unsigned int, int *, int, char *)); - -static struct symbol * -mylookup_symbol PARAMS ((char *, struct block *, enum namespace, - enum address_class)); - -static struct block * -shrink_block PARAMS ((struct block *, struct symtab *)); - -static PTR -xzalloc PARAMS ((unsigned int)); - -static void -sort_blocks PARAMS ((struct symtab *)); - -static int -compare_blocks PARAMS ((const void *, const void *)); - -static struct partial_symtab * -new_psymtab PARAMS ((char *, struct objfile *, struct section_offsets *)); - -static void -psymtab_to_symtab_1 PARAMS ((struct partial_symtab *, char *)); - -static void -add_block PARAMS ((struct block *, struct symtab *)); - -static void -add_symbol PARAMS ((struct symbol *, struct block *)); - -static int -add_line PARAMS ((struct linetable *, int, CORE_ADDR, int)); - -static struct linetable * -shrink_linetable PARAMS ((struct linetable *)); - -static void -handle_psymbol_enumerators PARAMS ((struct objfile *, FDR *, int)); - -static char * -mdebug_next_symbol_text PARAMS ((void)); - -/* Address bounds for the signal trampoline in inferior, if any */ - -CORE_ADDR sigtramp_address, sigtramp_end; - -/* Allocate zeroed memory */ - -static PTR -xzalloc (size) - unsigned int size; -{ - PTR p = xmalloc (size); - - memset (p, 0, size); - return p; -} - -/* Exported procedure: Builds a symtab from the PST partial one. - Restores the environment in effect when PST was created, delegates - most of the work to an ancillary procedure, and sorts - and reorders the symtab list at the end */ - -static void -mdebug_psymtab_to_symtab (pst) - struct partial_symtab *pst; -{ - - if (!pst) - return; - - if (info_verbose) - { - printf_filtered ("Reading in symbols for %s...", pst->filename); - gdb_flush (gdb_stdout); - } - - next_symbol_text_func = mdebug_next_symbol_text; - - psymtab_to_symtab_1 (pst, pst->filename); - - /* 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); - - if (info_verbose) - printf_filtered ("done.\n"); -} - -/* File-level interface functions */ - -/* Find a file descriptor given its index RF relative to a file CF */ - -static FDR * -get_rfd (cf, rf) - int cf, rf; -{ - FDR *fdrs; - register FDR *f; - RFDT rfd; - - fdrs = debug_info->fdr; - f = fdrs + cf; - /* Object files do not have the RFD table, all refs are absolute */ - if (f->rfdBase == 0) - return fdrs + rf; - (*debug_swap->swap_rfd_in) (cur_bfd, - ((char *) debug_info->external_rfd - + ((f->rfdBase + rf) - * debug_swap->external_rfd_size)), - &rfd); - return fdrs + rfd; -} - -/* Return a safer print NAME for a file descriptor */ - -static char * -fdr_name (f) - FDR *f; -{ - if (f->rss == -1) - return ""; - if (f->rss == 0) - return ""; - return debug_info->ss + f->issBase + f->rss; -} - - -/* Read in and parse the symtab of the file OBJFILE. Symbols from - different sections are relocated via the SECTION_OFFSETS. */ - -void -mdebug_build_psymtabs (objfile, swap, info, section_offsets) - struct objfile *objfile; - const struct ecoff_debug_swap *swap; - struct ecoff_debug_info *info; - struct section_offsets *section_offsets; -{ - cur_bfd = objfile->obfd; - debug_swap = swap; - debug_info = info; - - /* Make sure all the FDR information is swapped in. */ - if (info->fdr == (FDR *) NULL) - { - char *fdr_src; - char *fdr_end; - FDR *fdr_ptr; - - info->fdr = (FDR *) obstack_alloc (&objfile->psymbol_obstack, - (info->symbolic_header.ifdMax - * sizeof (FDR))); - fdr_src = info->external_fdr; - fdr_end = (fdr_src - + info->symbolic_header.ifdMax * swap->external_fdr_size); - fdr_ptr = info->fdr; - for (; fdr_src < fdr_end; fdr_src += swap->external_fdr_size, fdr_ptr++) - (*swap->swap_fdr_in) (objfile->obfd, fdr_src, fdr_ptr); - } - - parse_partial_symbols (objfile, section_offsets); - -#if 0 - /* Check to make sure file was compiled with -g. If not, warn the - user of this limitation. */ - if (compare_glevel (max_glevel, GLEVEL_2) < 0) - { - if (max_gdbinfo == 0) - printf_unfiltered ("\n%s not compiled with -g, debugging support is limited.\n", - objfile->name); - printf_unfiltered ("You should compile with -g2 or -g3 for best debugging support.\n"); - gdb_flush (gdb_stdout); - } -#endif -} - -/* Local utilities */ - -/* Map of FDR indexes to partial symtabs */ - -struct pst_map -{ - struct partial_symtab *pst; /* the psymtab proper */ - long n_globals; /* exported globals (external symbols) */ - long globals_offset; /* cumulative */ -}; - - -/* Utility stack, used to nest procedures and blocks properly. - It is a doubly linked list, to avoid too many alloc/free. - Since we might need it quite a few times it is NOT deallocated - after use. */ - -static struct parse_stack -{ - struct parse_stack *next, *prev; - struct symtab *cur_st; /* Current symtab. */ - struct block *cur_block; /* Block in it. */ - - /* What are we parsing. stFile, or stBlock are for files and - blocks. stProc or stStaticProc means we have seen the start of a - procedure, but not the start of the block within in. When we see - the start of that block, we change it to stNil, without pushing a - new block, i.e. stNil means both a procedure and a block. */ - - int blocktype; - - int maxsyms; /* Max symbols in this block. */ - struct type *cur_type; /* Type we parse fields for. */ - int cur_field; /* Field number in cur_type. */ - CORE_ADDR procadr; /* Start addres of this procedure */ - int numargs; /* Its argument count */ -} - - *top_stack; /* Top stack ptr */ - - -/* Enter a new lexical context */ - -static void -push_parse_stack () -{ - struct parse_stack *new; - - /* Reuse frames if possible */ - if (top_stack && top_stack->prev) - new = top_stack->prev; - else - new = (struct parse_stack *) xzalloc (sizeof (struct parse_stack)); - /* Initialize new frame with previous content */ - if (top_stack) - { - register struct parse_stack *prev = new->prev; - - *new = *top_stack; - top_stack->prev = new; - new->prev = prev; - new->next = top_stack; - } - top_stack = new; -} - -/* Exit a lexical context */ - -static void -pop_parse_stack () -{ - if (!top_stack) - return; - if (top_stack->next) - top_stack = top_stack->next; -} - - -/* Cross-references might be to things we haven't looked at - yet, e.g. type references. To avoid too many type - duplications we keep a quick fixup table, an array - of lists of references indexed by file descriptor */ - -struct mdebug_pending -{ - struct mdebug_pending *next; /* link */ - char *s; /* the unswapped symbol */ - struct type *t; /* its partial type descriptor */ -}; - - -/* The pending information is kept for an entire object file, and used - to be in the sym_private field. I took it out when I split - mdebugread from mipsread, because this might not be the only type - of symbols read from an object file. Instead, we allocate the - pending information table when we create the partial symbols, and - we store a pointer to the single table in each psymtab. */ - -static struct mdebug_pending **pending_list; - -/* Check whether we already saw symbol SH in file FH */ - -static struct mdebug_pending * -is_pending_symbol (fh, sh) - FDR *fh; - char *sh; -{ - int f_idx = fh - debug_info->fdr; - register struct mdebug_pending *p; - - /* Linear search is ok, list is typically no more than 10 deep */ - for (p = pending_list[f_idx]; p; p = p->next) - if (p->s == sh) - break; - return p; -} - -/* Add a new symbol SH of type T */ - -static void -add_pending (fh, sh, t) - FDR *fh; - char *sh; - struct type *t; -{ - int f_idx = fh - debug_info->fdr; - struct mdebug_pending *p = is_pending_symbol (fh, sh); - - /* Make sure we do not make duplicates */ - if (!p) - { - p = ((struct mdebug_pending *) - obstack_alloc (¤t_objfile->psymbol_obstack, - sizeof (struct mdebug_pending))); - p->s = sh; - p->t = t; - p->next = pending_list[f_idx]; - pending_list[f_idx] = p; - } -} - - -/* Parsing Routines proper. */ - -/* Parse a single symbol. Mostly just make up a GDB symbol for it. - For blocks, procedures and types we open a new lexical context. - This is basically just a big switch on the symbol's type. Argument - AX is the base pointer of aux symbols for this file (fh->iauxBase). - EXT_SH points to the unswapped symbol, which is needed for struct, - union, etc., types; it is NULL for an EXTR. BIGEND says whether - aux symbols are big-endian or little-endian. Return count of - SYMR's handled (normally one). */ - -static int -parse_symbol (sh, ax, ext_sh, bigend, section_offsets) - SYMR *sh; - union aux_ext *ax; - char *ext_sh; - int bigend; - struct section_offsets *section_offsets; -{ - const bfd_size_type external_sym_size = debug_swap->external_sym_size; - void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) = - debug_swap->swap_sym_in; - char *name; - struct symbol *s; - struct block *b; - struct mdebug_pending *pend; - struct type *t; - struct field *f; - int count = 1; - enum address_class class; - TIR tir; - long svalue = sh->value; - int bitsize; - - if (ext_sh == (char *) NULL) - name = debug_info->ssext + sh->iss; - else - name = debug_info->ss + cur_fdr->issBase + sh->iss; - - switch (sh->sc) - { - case scText: - /* The value of a stEnd symbol is the displacement from the - corresponding start symbol value, do not relocate it. */ - if (sh->st != stEnd) - sh->value += ANOFFSET (section_offsets, SECT_OFF_TEXT); - break; - case scData: - case scSData: - case scRData: - case scPData: - case scXData: - sh->value += ANOFFSET (section_offsets, SECT_OFF_DATA); - break; - case scBss: - case scSBss: - sh->value += ANOFFSET (section_offsets, SECT_OFF_BSS); - break; - } - - switch (sh->st) - { - case stNil: - break; - - case stGlobal: /* external symbol, goes into global block */ - class = LOC_STATIC; - b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (top_stack->cur_st), - GLOBAL_BLOCK); - s = new_symbol (name); - SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value; - goto data; - - case stStatic: /* static data, goes into current block. */ - class = LOC_STATIC; - b = top_stack->cur_block; - s = new_symbol (name); - if (sh->sc == scCommon) - { - /* 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 - scan_file_globals. */ - int bucket = hashname (SYMBOL_NAME (s)); - SYMBOL_VALUE_CHAIN (s) = global_sym_chain[bucket]; - global_sym_chain[bucket] = s; - } - else - SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value; - goto data; - - case stLocal: /* local variable, goes into current block */ - if (sh->sc == scRegister) - { - class = LOC_REGISTER; - svalue = ECOFF_REG_TO_REGNUM (svalue); - } - else - class = LOC_LOCAL; - b = top_stack->cur_block; - s = new_symbol (name); - SYMBOL_VALUE (s) = svalue; - - data: /* Common code for symbols describing data */ - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; - SYMBOL_CLASS (s) = class; - add_symbol (s, b); - - /* Type could be missing in a number of cases */ - if (sh->sc == scUndefined || sh->sc == scNil) - SYMBOL_TYPE (s) = builtin_type_int; /* undefined? */ - else - SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name); - /* Value of a data symbol is its memory address */ - break; - - case stParam: /* arg to procedure, goes into current block */ - max_gdbinfo++; - top_stack->numargs++; - - /* Special GNU C++ name. */ - if (name[0] == CPLUS_MARKER && name[1] == 't' && name[2] == 0) - name = "this"; /* FIXME, not alloc'd in obstack */ - s = new_symbol (name); - - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; - switch (sh->sc) - { - case scRegister: - /* Pass by value in register. */ - SYMBOL_CLASS(s) = LOC_REGPARM; - svalue = ECOFF_REG_TO_REGNUM (svalue); - break; - case scVar: - /* Pass by reference on stack. */ - SYMBOL_CLASS(s) = LOC_REF_ARG; - break; - case scVarRegister: - /* Pass by reference in register. */ - SYMBOL_CLASS(s) = LOC_REGPARM_ADDR; - svalue = ECOFF_REG_TO_REGNUM (svalue); - break; - default: - /* Pass by value on stack. */ - SYMBOL_CLASS(s) = LOC_ARG; - break; - } - SYMBOL_VALUE (s) = svalue; - SYMBOL_TYPE (s) = parse_type (cur_fd, ax, sh->index, 0, bigend, name); - add_symbol (s, top_stack->cur_block); -#if 0 - /* FIXME: This has not been tested. See dbxread.c */ - /* Add the type of this parameter to the function/procedure - type of this block. */ - add_param_to_type (&top_stack->cur_block->function->type, s); -#endif - break; - - case stLabel: /* label, goes into current block */ - s = new_symbol (name); - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; /* so that it can be used */ - SYMBOL_CLASS (s) = LOC_LABEL; /* but not misused */ - SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value; - SYMBOL_TYPE (s) = builtin_type_int; - add_symbol (s, top_stack->cur_block); - break; - - case stProc: /* Procedure, usually goes into global block */ - case stStaticProc: /* Static procedure, goes into current block */ - s = new_symbol (name); - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; - SYMBOL_CLASS (s) = LOC_BLOCK; - /* Type of the return value */ - if (sh->sc == scUndefined || sh->sc == scNil) - t = builtin_type_int; - else - t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name); - b = top_stack->cur_block; - if (sh->st == stProc) - { - struct blockvector *bv = BLOCKVECTOR (top_stack->cur_st); - /* The next test should normally be true, but provides a - hook for nested functions (which we don't want to make - global). */ - if (b == BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) - b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - /* Irix 5 sometimes has duplicate names for the same - function. We want to add such names up at the global - level, not as a nested function. */ - else if (sh->value == top_stack->procadr) - b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - } - add_symbol (s, b); - - /* Make a type for the procedure itself */ -#if 0 - /* FIXME: This has not been tested yet! See dbxread.c */ - /* Generate a template for the type of this function. The - types of the arguments will be added as we read the symbol - table. */ - memcpy (lookup_function_type (t), SYMBOL_TYPE (s), sizeof (struct type)); -#else - SYMBOL_TYPE (s) = lookup_function_type (t); -#endif - - /* Create and enter a new lexical context */ - b = new_block (top_stack->maxsyms); - SYMBOL_BLOCK_VALUE (s) = b; - BLOCK_FUNCTION (b) = s; - BLOCK_START (b) = BLOCK_END (b) = sh->value; - BLOCK_SUPERBLOCK (b) = top_stack->cur_block; - add_block (b, top_stack->cur_st); - - /* Not if we only have partial info */ - if (sh->sc == scUndefined || sh->sc == scNil) - break; - - push_parse_stack (); - top_stack->cur_block = b; - top_stack->blocktype = sh->st; - top_stack->cur_type = SYMBOL_TYPE (s); - top_stack->cur_field = -1; - top_stack->procadr = sh->value; - top_stack->numargs = 0; - break; - - /* Beginning of code for structure, union, and enum definitions. - They all share a common set of local variables, defined here. */ - { - enum type_code type_code; - char *ext_tsym; - int nfields; - long max_value; - struct field *f; - - case stStruct: /* Start a block defining a struct type */ - type_code = TYPE_CODE_STRUCT; - goto structured_common; - - case stUnion: /* Start a block defining a union type */ - type_code = TYPE_CODE_UNION; - goto structured_common; - - case stEnum: /* Start a block defining an enum type */ - type_code = TYPE_CODE_ENUM; - goto structured_common; - - case stBlock: /* Either a lexical block, or some type */ - if (sh->sc != scInfo && sh->sc != scCommon) - goto case_stBlock_code; /* Lexical block */ - - type_code = TYPE_CODE_UNDEF; /* We have a type. */ - - /* Common code for handling struct, union, enum, and/or as-yet- - unknown-type blocks of info about structured data. `type_code' - has been set to the proper TYPE_CODE, if we know it. */ - structured_common: - push_parse_stack (); - top_stack->blocktype = stBlock; - - /* First count the number of fields and the highest value. */ - nfields = 0; - max_value = 0; - for (ext_tsym = ext_sh + external_sym_size; - ; - ext_tsym += external_sym_size) - { - SYMR tsym; - - (*swap_sym_in) (cur_bfd, ext_tsym, &tsym); - - switch (tsym.st) - { - case stEnd: - goto end_of_fields; - - case stMember: - if (nfields == 0 && type_code == TYPE_CODE_UNDEF) - /* If the type of the member is Nil (or Void), - without qualifiers, assume the tag is an - enumeration. */ - if (tsym.index == indexNil) - type_code = TYPE_CODE_ENUM; - else - { - (*debug_swap->swap_tir_in) (bigend, - &ax[tsym.index].a_ti, - &tir); - if ((tir.bt == btNil || tir.bt == btVoid) - && tir.tq0 == tqNil) - type_code = TYPE_CODE_ENUM; - } - nfields++; - if (tsym.value > max_value) - max_value = tsym.value; - break; - - case stBlock: - case stUnion: - case stEnum: - case stStruct: - { -#if 0 - /* This is a no-op; is it trying to tell us something - we should be checking? */ - if (tsym.sc == scVariant); /*UNIMPLEMENTED*/ -#endif - if (tsym.index != 0) - { - /* This is something like a struct within a - struct. Skip over the fields of the inner - struct. The -1 is because the for loop will - increment ext_tsym. */ - ext_tsym = ((char *) debug_info->external_sym - + ((cur_fdr->isymBase + tsym.index - 1) - * external_sym_size)); - } - } - break; - - case stTypedef: - /* mips cc puts out a typedef for struct x if it is not yet - defined when it encounters - struct y { struct x *xp; }; - Just ignore it. */ - break; - - case stIndirect: - /* Irix5 cc puts out a stIndirect for struct x if it is not - yet defined when it encounters - struct y { struct x *xp; }; - Just ignore it. */ - break; - - default: - complain (&block_member_complaint, tsym.st); - } - } - end_of_fields:; - - /* In an stBlock, there is no way to distinguish structs, - unions, and enums at this point. This is a bug in the - original design (that has been fixed with the recent - addition of the stStruct, stUnion, and stEnum symbol - types.) The way you can tell is if/when you see a variable - or field of that type. In that case the variable's type - (in the AUX table) says if the type is struct, union, or - enum, and points back to the stBlock here. So you can - patch the tag kind up later - but only if there actually is - a variable or field of that type. - - So until we know for sure, we will guess at this point. - The heuristic is: - If the first member has index==indexNil or a void type, - assume we have an enumeration. - Otherwise, if there is more than one member, and all - the members have offset 0, assume we have a union. - Otherwise, assume we have a struct. - - The heuristic could guess wrong in the case of of an - enumeration with no members or a union with one (or zero) - members, or when all except the last field of a struct have - width zero. These are uncommon and/or illegal situations, - and in any case guessing wrong probably doesn't matter - much. - - But if we later do find out we were wrong, we fixup the tag - kind. Members of an enumeration must be handled - differently from struct/union fields, and that is harder to - patch up, but luckily we shouldn't need to. (If there are - any enumeration members, we can tell for sure it's an enum - here.) */ - - if (type_code == TYPE_CODE_UNDEF) - if (nfields > 1 && max_value == 0) - type_code = TYPE_CODE_UNION; - else - type_code = TYPE_CODE_STRUCT; - - /* Create a new type or use the pending type. */ - pend = is_pending_symbol (cur_fdr, ext_sh); - if (pend == (struct mdebug_pending *) NULL) - { - t = new_type (NULL); - add_pending (cur_fdr, ext_sh, t); - } - else - t = pend->t; - - /* Do not set the tag name if it is a compiler generated tag name - (.Fxx or .xxfake or empty) for unnamed struct/union/enums. - Alpha cc puts out an sh->iss of zero for those. */ - if (sh->iss == 0 || name[0] == '.' || name[0] == '\0') - TYPE_TAG_NAME (t) = NULL; - else - TYPE_TAG_NAME (t) = obconcat (¤t_objfile->symbol_obstack, - "", "", name); - - TYPE_CODE (t) = type_code; - TYPE_LENGTH (t) = sh->value; - TYPE_NFIELDS (t) = nfields; - TYPE_FIELDS (t) = f = ((struct field *) - TYPE_ALLOC (t, - nfields * sizeof (struct field))); - - if (type_code == TYPE_CODE_ENUM) - { - /* This is a non-empty enum. */ - - /* DEC c89 has the number of enumerators in the sh.value field, - not the type length, so we have to compensate for that - incompatibility quirk. - This might do the wrong thing for an enum with one or two - enumerators and gcc -gcoff -fshort-enums, but these cases - are hopefully rare enough. */ - if (TYPE_LENGTH (t) == TYPE_NFIELDS (t)) - TYPE_LENGTH (t) = TARGET_INT_BIT / HOST_CHAR_BIT; - for (ext_tsym = ext_sh + external_sym_size; - ; - ext_tsym += external_sym_size) - { - SYMR tsym; - struct symbol *enum_sym; - - (*swap_sym_in) (cur_bfd, ext_tsym, &tsym); - - 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; - - enum_sym = ((struct symbol *) - obstack_alloc (¤t_objfile->symbol_obstack, - sizeof (struct symbol))); - memset ((PTR) enum_sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (enum_sym) = f->name; - SYMBOL_CLASS (enum_sym) = LOC_CONST; - SYMBOL_TYPE (enum_sym) = t; - SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE; - SYMBOL_VALUE (enum_sym) = tsym.value; - add_symbol (enum_sym, top_stack->cur_block); - - /* Skip the stMembers that we've handled. */ - count++; - f++; - } - } - /* make this the current type */ - top_stack->cur_type = t; - top_stack->cur_field = 0; - - /* Do not create a symbol for alpha cc unnamed structs. */ - if (sh->iss == 0) - break; - - /* gcc puts out an empty struct for an opaque struct definitions, - do not create a symbol for it either. */ - if (TYPE_NFIELDS (t) == 0) - { - TYPE_FLAGS (t) |= TYPE_FLAG_STUB; - break; - } - - s = new_symbol (name); - SYMBOL_NAMESPACE (s) = STRUCT_NAMESPACE; - SYMBOL_CLASS (s) = LOC_TYPEDEF; - SYMBOL_VALUE (s) = 0; - SYMBOL_TYPE (s) = t; - add_symbol (s, top_stack->cur_block); - break; - - /* End of local variables shared by struct, union, enum, and - block (as yet unknown struct/union/enum) processing. */ - } - - case_stBlock_code: - /* beginnning of (code) block. Value of symbol - is the displacement from procedure start */ - push_parse_stack (); - - /* Do not start a new block if this is the outermost block of a - procedure. This allows the LOC_BLOCK symbol to point to the - block with the local variables, so funcname::var works. */ - if (top_stack->blocktype == stProc - || top_stack->blocktype == stStaticProc) - { - top_stack->blocktype = stNil; - break; - } - - top_stack->blocktype = stBlock; - b = new_block (top_stack->maxsyms); - BLOCK_START (b) = sh->value + top_stack->procadr; - BLOCK_SUPERBLOCK (b) = top_stack->cur_block; - top_stack->cur_block = b; - add_block (b, top_stack->cur_st); - break; - - case stEnd: /* end (of anything) */ - if (sh->sc == scInfo || sh->sc == scCommon) - { - /* Finished with type */ - top_stack->cur_type = 0; - } - else if (sh->sc == scText && - (top_stack->blocktype == stProc || - top_stack->blocktype == stStaticProc)) - { - /* Finished with procedure */ - struct blockvector *bv = BLOCKVECTOR (top_stack->cur_st); - struct mips_extra_func_info *e; - struct block *b; - int i; - - BLOCK_END (top_stack->cur_block) += sh->value; /* size */ - - /* Make up special symbol to contain procedure specific info */ - s = new_symbol (MIPS_EFI_SYMBOL_NAME); - SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE; - SYMBOL_CLASS (s) = LOC_CONST; - SYMBOL_TYPE (s) = builtin_type_void; - e = ((struct mips_extra_func_info *) - obstack_alloc (¤t_objfile->symbol_obstack, - sizeof (struct mips_extra_func_info))); - SYMBOL_VALUE (s) = (long) e; - e->numargs = top_stack->numargs; - add_symbol (s, top_stack->cur_block); - - /* Reallocate symbols, saving memory */ - b = shrink_block (top_stack->cur_block, top_stack->cur_st); - - /* f77 emits proc-level with address bounds==[0,0], - So look for such child blocks, and patch them. */ - for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++) - { - struct block *b_bad = BLOCKVECTOR_BLOCK (bv, i); - if (BLOCK_SUPERBLOCK (b_bad) == b - && BLOCK_START (b_bad) == top_stack->procadr - && BLOCK_END (b_bad) == top_stack->procadr) - { - BLOCK_START (b_bad) = BLOCK_START (b); - BLOCK_END (b_bad) = BLOCK_END (b); - } - } - } - else if (sh->sc == scText && top_stack->blocktype == stBlock) - { - /* End of (code) block. The value of the symbol is the - displacement from the procedure`s start address of the - end of this block. */ - BLOCK_END (top_stack->cur_block) = sh->value + top_stack->procadr; - shrink_block (top_stack->cur_block, top_stack->cur_st); - } - else if (sh->sc == scText && top_stack->blocktype == stNil) - { - /* End of outermost block. Pop parse stack and ignore. The - following stEnd of stProc will take care of the block. */ - ; - } - else if (sh->sc == scText && top_stack->blocktype == stFile) - { - /* End of file. Pop parse stack and ignore. Higher - level code deals with this. */ - ; - } - else - complain (&stEnd_complaint, sh->sc); - - pop_parse_stack (); /* restore previous lexical context */ - break; - - 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; - bitsize = 0; - f->type = parse_type (cur_fd, ax, sh->index, &bitsize, bigend, name); - f->bitsize = bitsize; - break; - - case stIndirect: /* forward declaration on Irix5 */ - /* Forward declarations from Irix5 cc are handled by cross_ref, - skip them. */ - break; - - case stTypedef: /* type definition */ - /* Typedefs for forward declarations and opaque structs from alpha cc - are handled by cross_ref, skip them. */ - if (sh->iss == 0) - break; - - /* Parse the type or use the pending type. */ - pend = is_pending_symbol (cur_fdr, ext_sh); - if (pend == (struct mdebug_pending *) NULL) - { - t = parse_type (cur_fd, ax, sh->index, (int *)NULL, bigend, name); - add_pending (cur_fdr, ext_sh, t); - } - else - t = pend->t; - - /* mips cc puts out a typedef with the name of the struct for forward - declarations. These should not go into the symbol table and - TYPE_NAME should not be set for them. - They can't be distinguished from an intentional typedef to - the same name however: - x.h: - struct x { int ix; int jx; }; - struct xx; - x.c: - typedef struct x x; - struct xx {int ixx; int jxx; }; - generates a cross referencing stTypedef for x and xx. - The user visible effect of this is that the type of a pointer - to struct foo sometimes is given as `foo *' instead of `struct foo *'. - The problem is fixed with alpha cc and Irix5 cc. */ - - /* However if the typedef cross references to an opaque aggregate, it - is safe to omit it from the symbol table. */ - - if (has_opaque_xref (cur_fdr, sh)) - break; - s = new_symbol (name); - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; - SYMBOL_CLASS (s) = LOC_TYPEDEF; - SYMBOL_BLOCK_VALUE (s) = top_stack->cur_block; - SYMBOL_TYPE (s) = t; - add_symbol (s, top_stack->cur_block); - - /* Incomplete definitions of structs should not get a name. */ - if (TYPE_NAME (SYMBOL_TYPE (s)) == NULL - && (TYPE_NFIELDS (SYMBOL_TYPE (s)) != 0 - || (TYPE_CODE (SYMBOL_TYPE (s)) != TYPE_CODE_STRUCT - && TYPE_CODE (SYMBOL_TYPE (s)) != TYPE_CODE_UNION))) - { - if (TYPE_CODE (SYMBOL_TYPE (s)) == TYPE_CODE_PTR - || TYPE_CODE (SYMBOL_TYPE (s)) == TYPE_CODE_FUNC) - { - /* If we are giving a name to a type such as "pointer to - foo" or "function returning foo", we better not set - the TYPE_NAME. If the program contains "typedef char - *caddr_t;", we don't want all variables of type char - * to print as caddr_t. This is not just a - consequence of GDB's type management; CC and GCC (at - least through version 2.4) both output variables of - either type char * or caddr_t with the type - refering to the stTypedef symbol for caddr_t. If a future - compiler cleans this up it GDB is not ready for it - yet, but if it becomes ready we somehow need to - disable this check (without breaking the PCC/GCC2.4 - case). - - Sigh. - - Fortunately, this check seems not to be necessary - for anything except pointers or functions. */ - } - else - TYPE_NAME (SYMBOL_TYPE (s)) = SYMBOL_NAME (s); - } - break; - - case stFile: /* file name */ - push_parse_stack (); - top_stack->blocktype = sh->st; - break; - - /* I`ve never seen these for C */ - case stRegReloc: - break; /* register relocation */ - case stForward: - break; /* forwarding address */ - case stConstant: - break; /* constant */ - default: - complain (&unknown_mdebug_symtype_complaint, sh->st); - break; - } - - return count; -} - -/* Parse the type information provided in the raw AX entries for - the symbol SH. Return the bitfield size in BS, in case. - We must byte-swap the AX entries before we use them; BIGEND says whether - they are big-endian or little-endian (from fh->fBigendian). */ - -static struct type * -parse_type (fd, ax, aux_index, bs, bigend, sym_name) - int fd; - union aux_ext *ax; - unsigned int aux_index; - int *bs; - int bigend; - char *sym_name; -{ - /* Null entries in this map are treated specially */ - static struct type **map_bt[] = - { - &builtin_type_void, /* btNil */ - 0, /* btAdr */ - &builtin_type_char, /* btChar */ - &builtin_type_unsigned_char,/* btUChar */ - &builtin_type_short, /* btShort */ - &builtin_type_unsigned_short, /* btUShort */ - &builtin_type_int, /* btInt */ - &builtin_type_unsigned_int, /* btUInt */ - &builtin_type_long, /* btLong */ - &builtin_type_unsigned_long,/* btULong */ - &builtin_type_float, /* btFloat */ - &builtin_type_double, /* btDouble */ - 0, /* btStruct */ - 0, /* btUnion */ - 0, /* btEnum */ - 0, /* btTypedef */ - 0, /* btRange */ - 0, /* btSet */ - &mdebug_type_complex, /* btComplex */ - &mdebug_type_double_complex, /* btDComplex */ - 0, /* btIndirect */ - &mdebug_type_fixed_dec, /* btFixedDec */ - &mdebug_type_float_dec, /* btFloatDec */ - &mdebug_type_string, /* btString */ - 0, /* btBit */ - 0, /* btPicture */ - &builtin_type_void, /* btVoid */ - 0, /* DEC C++: Pointer to member */ - 0, /* DEC C++: Virtual function table */ - 0, /* DEC C++: Class (Record) */ - &builtin_type_long, /* btLong64 */ - &builtin_type_unsigned_long, /* btULong64 */ - &builtin_type_long_long, /* btLongLong64 */ - &builtin_type_unsigned_long_long, /* btULongLong64 */ - &builtin_type_unsigned_long, /* btAdr64 */ - &builtin_type_long, /* btInt64 */ - &builtin_type_unsigned_long, /* btUInt64 */ - }; - - TIR t[1]; - struct type *tp = 0; - enum type_code type_code = TYPE_CODE_UNDEF; - - /* Handle undefined types, they have indexNil. */ - if (aux_index == indexNil) - return builtin_type_int; - - /* Handle corrupt aux indices. */ - if (aux_index >= (debug_info->fdr + fd)->caux) - { - complain (&index_complaint, sym_name); - return builtin_type_int; - } - ax += aux_index; - - /* Use aux as a type information record, map its basic type. */ - (*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t); - if (t->bt >= (sizeof (map_bt) / sizeof (*map_bt))) - { - complain (&basic_type_complaint, t->bt, sym_name); - return builtin_type_int; - } - if (map_bt[t->bt]) - { - tp = *map_bt[t->bt]; - } - else - { - tp = NULL; - /* Cannot use builtin types -- build our own */ - switch (t->bt) - { - case btAdr: - tp = lookup_pointer_type (builtin_type_void); - break; - case btStruct: - type_code = TYPE_CODE_STRUCT; - break; - case btUnion: - type_code = TYPE_CODE_UNION; - break; - case btEnum: - type_code = TYPE_CODE_ENUM; - break; - case btRange: - type_code = TYPE_CODE_RANGE; - break; - case btSet: - type_code = TYPE_CODE_SET; - break; - case btTypedef: - /* alpha cc uses this for typedefs. The true type will be - obtained by crossreferencing below. */ - type_code = TYPE_CODE_ERROR; - break; - default: - complain (&basic_type_complaint, t->bt, sym_name); - return builtin_type_int; - } - } - - /* Move on to next aux */ - ax++; - - if (t->fBitfield) - { - /* Inhibit core dumps with some cfront generated objects that - corrupt the TIR. */ - if (bs == (int *)NULL) - { - complain (&bad_fbitfield_complaint, sym_name); - return builtin_type_int; - } - *bs = AUX_GET_WIDTH (bigend, ax); - ax++; - } - - /* All these types really point to some (common) MIPS type - definition, and only the type-qualifiers fully identify - them. We'll make the same effort at sharing. */ - if (t->bt == btStruct || - t->bt == btUnion || - t->bt == btEnum || - - /* btSet (I think) implies that the name is a tag name, not a typedef - name. This apparently is a MIPS extension for C sets. */ - t->bt == btSet) - { - char *name; - - /* Try to cross reference this type, build new type on failure. */ - ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name); - if (tp == (struct type *) NULL) - tp = init_type (type_code, 0, 0, (char *) NULL, current_objfile); - - /* DEC c89 produces cross references to qualified aggregate types, - dereference them. */ - while (TYPE_CODE (tp) == TYPE_CODE_PTR - || TYPE_CODE (tp) == TYPE_CODE_ARRAY) - tp = tp->target_type; - - /* Make sure that TYPE_CODE(tp) has an expected type code. - Any type may be returned from cross_ref if file indirect entries - are corrupted. */ - if (TYPE_CODE (tp) != TYPE_CODE_STRUCT - && TYPE_CODE (tp) != TYPE_CODE_UNION - && TYPE_CODE (tp) != TYPE_CODE_ENUM) - { - complain (&unexpected_type_code_complaint, sym_name); - } - else - { - - /* Usually, TYPE_CODE(tp) is already type_code. The main - exception is if we guessed wrong re struct/union/enum. - But for struct vs. union a wrong guess is harmless, so - don't complain(). */ - if ((TYPE_CODE (tp) == TYPE_CODE_ENUM - && type_code != TYPE_CODE_ENUM) - || (TYPE_CODE (tp) != TYPE_CODE_ENUM - && type_code == TYPE_CODE_ENUM)) - { - complain (&bad_tag_guess_complaint, sym_name); - } - - if (TYPE_CODE (tp) != type_code) - { - TYPE_CODE (tp) = type_code; - } - - /* Do not set the tag name if it is a compiler generated tag name - (.Fxx or .xxfake or empty) for unnamed struct/union/enums. */ - if (name[0] == '.' || name[0] == '\0') - TYPE_TAG_NAME (tp) = NULL; - else if (TYPE_TAG_NAME (tp) == NULL - || !STREQ (TYPE_TAG_NAME (tp), name)) - TYPE_TAG_NAME (tp) = obsavestring (name, strlen (name), - ¤t_objfile->type_obstack); - } - } - - /* All these types really point to some (common) MIPS type - definition, and only the type-qualifiers fully identify - them. We'll make the same effort at sharing. - FIXME: btIndirect cannot happen here as it is handled by the - switch t->bt above. And we are not doing any guessing on range types. */ - if (t->bt == btIndirect || - t->bt == btRange) - { - char *name; - - /* Try to cross reference this type, build new type on failure. */ - ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name); - if (tp == (struct type *) NULL) - tp = init_type (type_code, 0, 0, (char *) NULL, current_objfile); - - /* Make sure that TYPE_CODE(tp) has an expected type code. - Any type may be returned from cross_ref if file indirect entries - are corrupted. */ - if (TYPE_CODE (tp) != TYPE_CODE_RANGE) - { - complain (&unexpected_type_code_complaint, sym_name); - } - else - { - /* Usually, TYPE_CODE(tp) is already type_code. The main - exception is if we guessed wrong re struct/union/enum. */ - if (TYPE_CODE (tp) != type_code) - { - complain (&bad_tag_guess_complaint, sym_name); - TYPE_CODE (tp) = type_code; - } - if (TYPE_NAME (tp) == NULL || !STREQ (TYPE_NAME (tp), name)) - TYPE_NAME (tp) = obsavestring (name, strlen (name), - ¤t_objfile->type_obstack); - } - } - if (t->bt == btTypedef) - { - char *name; - - /* Try to cross reference this type, it should succeed. */ - ax += cross_ref (fd, ax, &tp, type_code, &name, bigend, sym_name); - if (tp == (struct type *) NULL) - { - complain (&unable_to_cross_ref_complaint, sym_name); - tp = builtin_type_int; - } - } - - /* Deal with range types */ - if (t->bt == btRange) - { - TYPE_NFIELDS (tp) = 2; - TYPE_FIELDS (tp) = ((struct field *) - TYPE_ALLOC (tp, 2 * sizeof (struct field))); - TYPE_FIELD_NAME (tp, 0) = obsavestring ("Low", strlen ("Low"), - ¤t_objfile->type_obstack); - TYPE_FIELD_BITPOS (tp, 0) = AUX_GET_DNLOW (bigend, ax); - ax++; - TYPE_FIELD_NAME (tp, 1) = obsavestring ("High", strlen ("High"), - ¤t_objfile->type_obstack); - TYPE_FIELD_BITPOS (tp, 1) = AUX_GET_DNHIGH (bigend, ax); - ax++; - } - - /* Parse all the type qualifiers now. If there are more - than 6 the game will continue in the next aux */ - - while (1) - { -#define PARSE_TQ(tq) \ - if (t->tq != tqNil) \ - ax += upgrade_type(fd, &tp, t->tq, ax, bigend, sym_name); \ - else \ - break; - - PARSE_TQ (tq0); - PARSE_TQ (tq1); - PARSE_TQ (tq2); - PARSE_TQ (tq3); - PARSE_TQ (tq4); - PARSE_TQ (tq5); -#undef PARSE_TQ - - /* mips cc 2.x and gcc never put out continued aux entries. */ - if (!t->continued) - break; - - (*debug_swap->swap_tir_in) (bigend, &ax->a_ti, t); - ax++; - } - - /* Complain for illegal continuations due to corrupt aux entries. */ - if (t->continued) - complain (&bad_continued_complaint, sym_name); - - return tp; -} - -/* Make up a complex type from a basic one. Type is passed by - reference in TPP and side-effected as necessary. The type - qualifier TQ says how to handle the aux symbols at AX for - the symbol SX we are currently analyzing. BIGEND says whether - aux symbols are big-endian or little-endian. - Returns the number of aux symbols we parsed. */ - -static int -upgrade_type (fd, tpp, tq, ax, bigend, sym_name) - int fd; - struct type **tpp; - int tq; - union aux_ext *ax; - int bigend; - char *sym_name; -{ - int off; - struct type *t; - - /* Used in array processing */ - int rf, id; - FDR *fh; - struct type *range; - struct type *indx; - int lower, upper; - RNDXR rndx; - - switch (tq) - { - case tqPtr: - t = lookup_pointer_type (*tpp); - *tpp = t; - return 0; - - case tqProc: - t = lookup_function_type (*tpp); - *tpp = t; - return 0; - - case tqArray: - off = 0; - - /* Determine and record the domain type (type of index) */ - (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, &rndx); - id = rndx.index; - rf = rndx.rfd; - if (rf == 0xfff) - { - ax++; - rf = AUX_GET_ISYM (bigend, ax); - off++; - } - fh = get_rfd (fd, rf); - - indx = parse_type (fd, debug_info->external_aux + fh->iauxBase, - id, (int *) NULL, bigend, sym_name); - - /* The bounds type should be an integer type, but might be anything - else due to corrupt aux entries. */ - if (TYPE_CODE (indx) != TYPE_CODE_INT) - { - complain (&array_index_type_complaint, sym_name); - indx = builtin_type_int; - } - - /* Get the bounds, and create the array type. */ - ax++; - lower = AUX_GET_DNLOW (bigend, ax); - ax++; - upper = AUX_GET_DNHIGH (bigend, ax); - ax++; - rf = AUX_GET_WIDTH (bigend, ax); /* bit size of array element */ - - range = create_range_type ((struct type *) NULL, indx, - lower, upper); - - t = create_array_type ((struct type *) NULL, *tpp, range); - - /* We used to fill in the supplied array element bitsize - here if the TYPE_LENGTH of the target type was zero. - This happens for a `pointer to an array of anonymous structs', - but in this case the array element bitsize is also zero, - so nothing is gained. - And we used to check the TYPE_LENGTH of the target type against - the supplied array element bitsize. - gcc causes a mismatch for `pointer to array of object', - since the sdb directives it uses do not have a way of - specifying the bitsize, but it does no harm (the - TYPE_LENGTH should be correct) and we should be able to - ignore the erroneous bitsize from the auxiliary entry safely. - dbx seems to ignore it too. */ - - *tpp = t; - return 4 + off; - - case tqVol: - /* Volatile -- currently ignored */ - return 0; - - case tqConst: - /* Const -- currently ignored */ - return 0; - - default: - complain (&unknown_type_qual_complaint, tq); - return 0; - } -} - - -/* Parse a procedure descriptor record PR. Note that the procedure is - parsed _after_ the local symbols, now we just insert the extra - information we need into a MIPS_EFI_SYMBOL_NAME symbol that has - already been placed in the procedure's main block. Note also that - images that have been partially stripped (ld -x) have been deprived - of local symbols, and we have to cope with them here. FIRST_OFF is - the offset of the first procedure for this FDR; we adjust the - address by this amount, but I don't know why. SEARCH_SYMTAB is the symtab - 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 *, unsigned long, - struct partial_symtab *)); - -static void -parse_procedure (pr, search_symtab, first_off, pst) - PDR *pr; - struct symtab *search_symtab; - unsigned long first_off; - struct partial_symtab *pst; -{ - struct symbol *s, *i; - struct block *b; - struct mips_extra_func_info *e; - char *sh_name; - - /* Simple rule to find files linked "-x" */ - if (cur_fdr->rss == -1) - { - if (pr->isym == -1) - { - /* Static procedure at address pr->adr. Sigh. */ - /* FIXME-32x64. assuming pr->adr fits in long. */ - complain (&pdr_static_symbol_complaint, (unsigned long) pr->adr); - return; - } - else - { - /* external */ - EXTR she; - - (*debug_swap->swap_ext_in) (cur_bfd, - ((char *) debug_info->external_ext - + (pr->isym - * debug_swap->external_ext_size)), - &she); - sh_name = debug_info->ssext + she.asym.iss; - } - } - else - { - /* Full symbols */ - SYMR sh; - - (*debug_swap->swap_sym_in) (cur_bfd, - ((char *) debug_info->external_sym - + ((cur_fdr->isymBase + pr->isym) - * debug_swap->external_sym_size)), - &sh); - sh_name = debug_info->ss + cur_fdr->issBase + sh.iss; - } - - if (search_symtab != NULL) - { -#if 0 - /* This loses both in the case mentioned (want a static, find a global), - but also if we are looking up a non-mangled name which happens to - match the name of a mangled function. */ - /* We have to save the cur_fdr across the call to lookup_symbol. - If the pdr is for a static function and if a global function with - the same name exists, lookup_symbol will eventually read in the symtab - for the global function and clobber cur_fdr. */ - FDR *save_cur_fdr = cur_fdr; - s = lookup_symbol (sh_name, NULL, VAR_NAMESPACE, 0, NULL); - cur_fdr = save_cur_fdr; -#else - s = mylookup_symbol - (sh_name, - BLOCKVECTOR_BLOCK (BLOCKVECTOR (search_symtab), STATIC_BLOCK), - VAR_NAMESPACE, - LOC_BLOCK); -#endif - } - else - s = mylookup_symbol (sh_name, top_stack->cur_block, - VAR_NAMESPACE, LOC_BLOCK); - - if (s != 0) - { - b = SYMBOL_BLOCK_VALUE (s); - } - else - { - complain (&pdr_for_nonsymbol_complaint, sh_name); -#if 1 - return; -#else -/* FIXME -- delete. We can't do symbol allocation now; it's all done. */ - s = new_symbol (sh_name); - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; - SYMBOL_CLASS (s) = LOC_BLOCK; - /* Donno its type, hope int is ok */ - SYMBOL_TYPE (s) = lookup_function_type (builtin_type_int); - add_symbol (s, top_stack->cur_block); - /* Wont have symbols for this one */ - b = new_block (2); - SYMBOL_BLOCK_VALUE (s) = b; - BLOCK_FUNCTION (b) = s; - BLOCK_START (b) = pr->adr; - /* BOUND used to be the end of procedure's text, but the - argument is no longer passed in. */ - BLOCK_END (b) = bound; - BLOCK_SUPERBLOCK (b) = top_stack->cur_block; - add_block (b, top_stack->cur_st); -#endif - } - - i = mylookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, LOC_CONST); - - if (i) - { - e = (struct mips_extra_func_info *) SYMBOL_VALUE (i); - e->pdr = *pr; - e->pdr.isym = (long) s; - e->pdr.adr += pst->textlow - first_off; - - /* Correct incorrect setjmp procedure descriptor from the library - to make backtrace through setjmp work. */ - if (e->pdr.pcreg == 0 && STREQ (sh_name, "setjmp")) - { - complain (&bad_setjmp_pdr_complaint, 0); - e->pdr.pcreg = RA_REGNUM; - e->pdr.regmask = 0x80000000; - e->pdr.regoffset = -4; - } - } -} - -/* Relocate the extra function info pointed to by the symbol table. */ - -void -ecoff_relocate_efi (sym, delta) - struct symbol *sym; - CORE_ADDR delta; -{ - struct mips_extra_func_info *e; - - e = (struct mips_extra_func_info *) SYMBOL_VALUE (sym); - - e->pdr.adr += delta; -} - -/* Parse the external symbol ES. Just call parse_symbol() after - making sure we know where the aux are for it. - BIGEND says whether aux entries are big-endian or little-endian. - - This routine clobbers top_stack->cur_block and ->cur_st. */ - -static void parse_external PARAMS ((EXTR *, int, struct section_offsets *)); - -static void -parse_external (es, bigend, section_offsets) - EXTR *es; - int bigend; - struct section_offsets *section_offsets; -{ - union aux_ext *ax; - - if (es->ifd != ifdNil) - { - cur_fd = es->ifd; - cur_fdr = debug_info->fdr + cur_fd; - ax = debug_info->external_aux + cur_fdr->iauxBase; - } - else - { - cur_fdr = debug_info->fdr; - ax = 0; - } - - /* Reading .o files */ - if (es->asym.sc == scUndefined || es->asym.sc == scNil) - { - char *what; - switch (es->asym.st) - { - case stNil: - /* These are generated for static symbols in .o files, - ignore them. */ - return; - case stStaticProc: - case stProc: - what = "procedure"; - n_undef_procs++; - break; - case stGlobal: - what = "variable"; - n_undef_vars++; - break; - case stLabel: - what = "label"; - n_undef_labels++; - break; - default: - what = "symbol"; - break; - } - n_undef_symbols++; - /* FIXME: Turn this into a complaint? */ - if (info_verbose) - printf_filtered ("Warning: %s `%s' is undefined (in %s)\n", - what, debug_info->ssext + es->asym.iss, - fdr_name (cur_fdr)); - return; - } - - switch (es->asym.st) - { - case stProc: - case stStaticProc: - /* There is no need to parse the external procedure symbols. - If they are from objects compiled without -g, their index will - be indexNil, and the symbol definition from the minimal symbol - is preferrable (yielding a function returning int instead of int). - If the index points to a local procedure symbol, the local - symbol already provides the correct type. - Note that the index of the external procedure symbol points - to the local procedure symbol in the local symbol table, and - _not_ to the auxiliary symbol info. */ - break; - case stGlobal: - case stLabel: - /* Note that the case of a symbol with indexNil must be handled - anyways by parse_symbol(). */ - parse_symbol (&es->asym, ax, (char *) NULL, bigend, section_offsets); - break; - default: - break; - } -} - -/* Parse the line number info for file descriptor FH into - GDB's linetable LT. MIPS' encoding requires a little bit - of magic to get things out. Note also that MIPS' line - numbers can go back and forth, apparently we can live - with that and do not need to reorder our linetables */ - -static void parse_lines PARAMS ((FDR *, PDR *, struct linetable *, int, - struct partial_symtab *)); - -static void -parse_lines (fh, pr, lt, maxlines, pst) - FDR *fh; - PDR *pr; - struct linetable *lt; - int maxlines; - struct partial_symtab *pst; -{ - unsigned char *base; - int j, k; - int delta, count, lineno = 0; - unsigned long first_off = pr->adr; - - if (fh->cbLine == 0) - return; - - /* Scan by procedure descriptors */ - k = 0; - for (j = 0; j < fh->cpd; j++, pr++) - { - long l; - unsigned long adr; - unsigned char *halt; - - /* No code for this one */ - if (pr->iline == ilineNil || - pr->lnLow == -1 || pr->lnHigh == -1) - continue; - - /* Determine start and end address of compressed line bytes for - this procedure. */ - base = debug_info->line + fh->cbLineOffset; - if (j != (fh->cpd - 1)) - halt = base + pr[1].cbLineOffset; - else - halt = base + fh->cbLine; - base += pr->cbLineOffset; - - adr = pst->textlow + pr->adr - first_off; - - l = adr >> 2; /* in words */ - for (lineno = pr->lnLow; base < halt; ) - { - count = *base & 0x0f; - delta = *base++ >> 4; - if (delta >= 8) - delta -= 16; - if (delta == -8) - { - delta = (base[0] << 8) | base[1]; - if (delta >= 0x8000) - delta -= 0x10000; - base += 2; - } - lineno += delta; /* first delta is 0 */ - - /* Complain if the line table overflows. Could happen - with corrupt binaries. */ - if (lt->nitems >= maxlines) - { - complain (&bad_linetable_guess_complaint, fdr_name (fh)); - break; - } - k = add_line (lt, lineno, l, k); - l += count + 1; - } - } -} - -/* Master parsing procedure for first-pass reading of file symbols - into a partial_symtab. */ - -static void -parse_partial_symbols (objfile, section_offsets) - struct objfile *objfile; - struct section_offsets *section_offsets; -{ - const bfd_size_type external_sym_size = debug_swap->external_sym_size; - const bfd_size_type external_rfd_size = debug_swap->external_rfd_size; - const bfd_size_type external_ext_size = debug_swap->external_ext_size; - void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *)) - = debug_swap->swap_ext_in; - void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) - = debug_swap->swap_sym_in; - void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *)) - = debug_swap->swap_rfd_in; - int f_idx, s_idx; - HDRR *hdr = &debug_info->symbolic_header; - /* Running pointers */ - FDR *fh; - char *ext_out; - char *ext_out_end; - EXTR *ext_block; - register EXTR *ext_in; - EXTR *ext_in_end; - SYMR sh; - struct partial_symtab *pst; - - int past_first_source_file = 0; - - /* List of current psymtab's include files */ - char **psymtab_include_list; - int includes_allocated; - int includes_used; - EXTR *extern_tab; - struct pst_map *fdr_to_pst; - /* Index within current psymtab dependency list */ - struct partial_symtab **dependency_list; - int dependencies_used, dependencies_allocated; - struct cleanup *old_chain; - char *name; - enum language prev_language; - asection *text_sect; - int relocatable = 0; - - /* Irix 5.2 shared libraries have a fh->adr field of zero, but - the shared libraries are prelinked at a high memory address. - We have to adjust the start address of the object file for this case, - by setting it to the start address of the first procedure in the file. - But we should do no adjustments if we are debugging a .o file, where - the text section (and fh->adr) really starts at zero. */ - text_sect = bfd_get_section_by_name (cur_bfd, ".text"); - if (text_sect != NULL - && (bfd_get_section_flags (cur_bfd, text_sect) & SEC_RELOC)) - relocatable = 1; - - extern_tab = (EXTR *) obstack_alloc (&objfile->psymbol_obstack, - sizeof (EXTR) * hdr->iextMax); - - includes_allocated = 30; - includes_used = 0; - psymtab_include_list = (char **) alloca (includes_allocated * - sizeof (char *)); - next_symbol_text_func = mdebug_next_symbol_text; - - dependencies_allocated = 30; - dependencies_used = 0; - dependency_list = - (struct partial_symtab **) alloca (dependencies_allocated * - sizeof (struct partial_symtab *)); - - last_source_file = NULL; - - /* - * Big plan: - * - * Only parse the Local and External symbols, and the Relative FDR. - * Fixup enough of the loader symtab to be able to use it. - * Allocate space only for the file's portions we need to - * look at. (XXX) - */ - - max_gdbinfo = 0; - max_glevel = MIN_GLEVEL; - - /* Allocate the map FDR -> PST. - Minor hack: -O3 images might claim some global data belongs - to FDR -1. We`ll go along with that */ - fdr_to_pst = (struct pst_map *) xzalloc ((hdr->ifdMax + 1) * sizeof *fdr_to_pst); - old_chain = make_cleanup (free, fdr_to_pst); - fdr_to_pst++; - { - struct partial_symtab *pst = new_psymtab ("", objfile, section_offsets); - fdr_to_pst[-1].pst = pst; - FDR_IDX (pst) = -1; - } - - /* Allocate the global pending list. */ - pending_list = - ((struct mdebug_pending **) - obstack_alloc (&objfile->psymbol_obstack, - hdr->ifdMax * sizeof (struct mdebug_pending *))); - memset ((PTR) pending_list, 0, - hdr->ifdMax * sizeof (struct mdebug_pending *)); - - /* Pass 0 over external syms: swap them in. */ - ext_block = (EXTR *) xmalloc (hdr->iextMax * sizeof (EXTR)); - make_cleanup (free, ext_block); - - ext_out = (char *) debug_info->external_ext; - ext_out_end = ext_out + hdr->iextMax * external_ext_size; - ext_in = ext_block; - for (; ext_out < ext_out_end; ext_out += external_ext_size, ext_in++) - (*swap_ext_in) (cur_bfd, ext_out, ext_in); - - /* Pass 1 over external syms: Presize and partition the list */ - ext_in = ext_block; - ext_in_end = ext_in + hdr->iextMax; - for (; ext_in < ext_in_end; ext_in++) - { - /* See calls to complain below. */ - if (ext_in->ifd >= -1 - && ext_in->ifd < hdr->ifdMax - && ext_in->asym.iss >= 0 - && ext_in->asym.iss < hdr->issExtMax) - fdr_to_pst[ext_in->ifd].n_globals++; - } - - /* Pass 1.5 over files: partition out global symbol space */ - s_idx = 0; - for (f_idx = -1; f_idx < hdr->ifdMax; f_idx++) - { - fdr_to_pst[f_idx].globals_offset = s_idx; - s_idx += fdr_to_pst[f_idx].n_globals; - 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; - - /* 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; - - 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) - { - /* The value of a common symbol is its size, not its address. - Ignore it. */ - 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); - } - - /* Pass 3 over files, over local syms: fill in static symbols */ - for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) - { - struct partial_symtab *save_pst; - EXTR *ext_ptr; - CORE_ADDR textlow; - - cur_fdr = fh = debug_info->fdr + f_idx; - - if (fh->csym == 0) - { - fdr_to_pst[f_idx].pst = NULL; - continue; - } - - /* Determine the start address for this object file from the - file header and relocate it, except for Irix 5.2 zero fh->adr. */ - if (fh->cpd) - { - textlow = fh->adr; - if (relocatable || textlow != 0) - textlow += ANOFFSET (section_offsets, SECT_OFF_TEXT); - } - else - textlow = 0; - pst = start_psymtab_common (objfile, section_offsets, - fdr_name (fh), - textlow, - objfile->global_psymbols.next, - objfile->static_psymbols.next); - pst->read_symtab_private = ((char *) - obstack_alloc (&objfile->psymbol_obstack, - sizeof (struct symloc))); - memset ((PTR) pst->read_symtab_private, 0, sizeof (struct symloc)); - - save_pst = pst; - FDR_IDX (pst) = f_idx; - CUR_BFD (pst) = cur_bfd; - DEBUG_SWAP (pst) = debug_swap; - DEBUG_INFO (pst) = debug_info; - PENDING_LIST (pst) = pending_list; - - /* The way to turn this into a symtab is to call... */ - pst->read_symtab = mdebug_psymtab_to_symtab; - - /* Set up language for the pst. - The language from the FDR is used if it is unambigious (e.g. cfront - with native cc and g++ will set the language to C). - Otherwise we have to deduce the language from the filename. - Native ecoff has every header file in a separate FDR, so - deduce_language_from_filename will return language_unknown for - a header file, which is not what we want. - But the FDRs for the header files are after the FDR for the source - file, so we can assign the language of the source file to the - following header files. Then we save the language in the private - pst data so that we can reuse it when building symtabs. */ - prev_language = psymtab_language; - - switch (fh->lang) - { - case langCplusplusV2: - psymtab_language = language_cplus; - break; - default: - psymtab_language = deduce_language_from_filename (fdr_name (fh)); - break; - } - if (psymtab_language == language_unknown) - psymtab_language = prev_language; - PST_PRIVATE (pst)->pst_language = psymtab_language; - - pst->texthigh = pst->textlow; - - /* For stabs-in-ecoff files, the second symbol must be @stab. - This symbol is emitted by mips-tfile to signal that the - current object file uses encapsulated stabs instead of mips - ecoff for local symbols. (It is the second symbol because - the first symbol is the stFile used to signal the start of a - file). */ - processing_gcc_compilation = 0; - if (fh->csym >= 2) - { - (*swap_sym_in) (cur_bfd, - ((char *) debug_info->external_sym - + (fh->isymBase + 1) * external_sym_size), - &sh); - if (STREQ (debug_info->ss + fh->issBase + sh.iss, stabs_symbol)) - processing_gcc_compilation = 2; - } - - if (processing_gcc_compilation != 0) - { - for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) - { - int type_code; - char *namestring; - - (*swap_sym_in) (cur_bfd, - (((char *) debug_info->external_sym) - + (fh->isymBase + cur_sdx) * external_sym_size), - &sh); - type_code = ECOFF_UNMARK_STAB (sh.index); - if (!ECOFF_IS_STAB (&sh)) - { - if (sh.st == stProc || sh.st == stStaticProc) - { - long procaddr; - long isym; - - sh.value += ANOFFSET (section_offsets, SECT_OFF_TEXT); - if (sh.st == stStaticProc) - { - namestring = debug_info->ss + fh->issBase + sh.iss; - prim_record_minimal_symbol_and_info (namestring, - sh.value, - mst_file_text, - NULL, - SECT_OFF_TEXT, - objfile); - } - procaddr = sh.value; - - isym = AUX_GET_ISYM (fh->fBigendian, - (debug_info->external_aux - + fh->iauxBase - + sh.index)); - (*swap_sym_in) (cur_bfd, - ((char *) debug_info->external_sym - + ((fh->isymBase + isym - 1) - * external_sym_size)), - &sh); - if (sh.st == stEnd) - { - long high = procaddr + sh.value; - - /* Kludge for Irix 5.2 zero fh->adr. */ - if (!relocatable - && (pst->textlow == 0 || procaddr < pst->textlow)) - pst->textlow = procaddr; - if (high > pst->texthigh) - pst->texthigh = high; - } - } - else if (sh.st == stStatic) - { - switch (sh.sc) - { - case scUndefined: - case scNil: - case scAbs: - break; - - case scData: - case scSData: - case scRData: - case scPData: - case scXData: - namestring = debug_info->ss + fh->issBase + sh.iss; - sh.value += ANOFFSET (section_offsets, SECT_OFF_DATA); - prim_record_minimal_symbol_and_info (namestring, - sh.value, - mst_file_data, - NULL, - SECT_OFF_DATA, - objfile); - break; - - default: - namestring = debug_info->ss + fh->issBase + sh.iss; - sh.value += ANOFFSET (section_offsets, SECT_OFF_BSS); - prim_record_minimal_symbol_and_info (namestring, - sh.value, - mst_file_bss, - NULL, - SECT_OFF_BSS, - objfile); - break; - } - } - continue; - } -#define SET_NAMESTRING() \ - namestring = debug_info->ss + fh->issBase + sh.iss -#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 HANDLE_RBRAC(val) \ - if ((val) > save_pst->texthigh) save_pst->texthigh = (val); -#include "partial-stab.h" - } - } - else - { - for (cur_sdx = 0; cur_sdx < fh->csym;) - { - char *name; - enum address_class class; - - (*swap_sym_in) (cur_bfd, - ((char *) debug_info->external_sym - + ((fh->isymBase + cur_sdx) - * external_sym_size)), - &sh); - - if (ECOFF_IS_STAB (&sh)) - { - cur_sdx++; - continue; - } - - /* Non absolute static symbols go into the minimal table. */ - if (sh.sc == scUndefined || sh.sc == scNil - || (sh.index == indexNil - && (sh.st != stStatic || sh.sc == scAbs))) - { - /* FIXME, premature? */ - cur_sdx++; - continue; - } - - name = debug_info->ss + fh->issBase + sh.iss; - - switch (sh.sc) - { - case scText: - /* The value of a stEnd symbol is the displacement from the - corresponding start symbol value, do not relocate it. */ - if (sh.st != stEnd) - sh.value += ANOFFSET (section_offsets, SECT_OFF_TEXT); - break; - case scData: - case scSData: - case scRData: - case scPData: - case scXData: - sh.value += ANOFFSET (section_offsets, SECT_OFF_DATA); - break; - case scBss: - case scSBss: - sh.value += ANOFFSET (section_offsets, SECT_OFF_BSS); - break; - } - - switch (sh.st) - { - long high; - long procaddr; - int new_sdx; - - case stStaticProc: - prim_record_minimal_symbol_and_info (name, sh.value, - mst_file_text, NULL, - SECT_OFF_TEXT, objfile); - - /* FALLTHROUGH */ - - case stProc: - /* Usually there is a local and a global stProc symbol - for a function. This means that the function name - has already been entered into the mimimal symbol table - while processing the global symbols in pass 2 above. - One notable exception is the PROGRAM name from - f77 compiled executables, it is only put out as - local stProc symbol, and a global MAIN__ stProc symbol - points to it. It doesn't matter though, as gdb is - still able to find the PROGRAM name via the partial - symbol table, and the MAIN__ symbol via the minimal - symbol table. */ - if (sh.st == stProc) - ADD_PSYMBOL_TO_LIST (name, strlen (name), - VAR_NAMESPACE, LOC_BLOCK, - objfile->global_psymbols, - sh.value, psymtab_language, objfile); - else - ADD_PSYMBOL_TO_LIST (name, strlen (name), - VAR_NAMESPACE, LOC_BLOCK, - objfile->static_psymbols, - sh.value, psymtab_language, objfile); - - /* Skip over procedure to next one. */ - if (sh.index >= hdr->iauxMax) - { - /* Should not happen, but does when cross-compiling - with the MIPS compiler. FIXME -- pull later. */ - complain (&index_complaint, name); - new_sdx = cur_sdx + 1; /* Don't skip at all */ - } - else - new_sdx = AUX_GET_ISYM (fh->fBigendian, - (debug_info->external_aux - + fh->iauxBase - + sh.index)); - procaddr = sh.value; - - if (new_sdx <= cur_sdx) - { - /* This should not happen either... FIXME. */ - complain (&aux_index_complaint, name); - new_sdx = cur_sdx + 1; /* Don't skip backward */ - } - - cur_sdx = new_sdx; - (*swap_sym_in) (cur_bfd, - ((char *) debug_info->external_sym - + ((fh->isymBase + cur_sdx - 1) - * external_sym_size)), - &sh); - if (sh.st != stEnd) - continue; - - /* Kludge for Irix 5.2 zero fh->adr. */ - if (!relocatable - && (pst->textlow == 0 || procaddr < pst->textlow)) - pst->textlow = procaddr; - - high = procaddr + sh.value; - if (high > pst->texthigh) - pst->texthigh = high; - continue; - - case stStatic: /* Variable */ - if (sh.sc == scData - || sh.sc == scSData - || sh.sc == scRData - || sh.sc == scPData - || sh.sc == scXData) - prim_record_minimal_symbol_and_info (name, sh.value, - mst_file_data, NULL, - SECT_OFF_DATA, - objfile); - else - prim_record_minimal_symbol_and_info (name, sh.value, - mst_file_bss, NULL, - SECT_OFF_BSS, - objfile); - class = LOC_STATIC; - break; - - case stIndirect:/* Irix5 forward declaration */ - /* Skip forward declarations from Irix5 cc */ - goto skip; - - case stTypedef:/* Typedef */ - /* Skip typedefs for forward declarations and opaque - structs from alpha and mips cc. */ - if (sh.iss == 0 || has_opaque_xref (fh, &sh)) - goto skip; - class = LOC_TYPEDEF; - break; - - case stConstant: /* Constant decl */ - class = LOC_CONST; - break; - - case stUnion: - case stStruct: - case stEnum: - case stBlock: /* { }, str, un, enum*/ - /* Do not create a partial symbol for cc unnamed aggregates - and gcc empty aggregates. */ - if ((sh.sc == scInfo || sh.sc == scCommon) - && sh.iss != 0 - && sh.index != cur_sdx + 2) - { - ADD_PSYMBOL_TO_LIST (name, strlen (name), - STRUCT_NAMESPACE, LOC_TYPEDEF, - objfile->static_psymbols, - sh.value, - psymtab_language, objfile); - } - handle_psymbol_enumerators (objfile, fh, sh.st); - - /* Skip over the block */ - new_sdx = sh.index; - if (new_sdx <= cur_sdx) - { - /* This happens with the Ultrix kernel. */ - complain (&block_index_complaint, name); - new_sdx = cur_sdx + 1; /* Don't skip backward */ - } - cur_sdx = new_sdx; - continue; - - case stFile: /* File headers */ - case stLabel: /* Labels */ - case stEnd: /* Ends of files */ - goto skip; - - case stLocal: /* Local variables */ - /* Normally these are skipped because we skip over - all blocks we see. However, these can occur - as visible symbols in a .h file that contains code. */ - goto skip; - - default: - /* Both complaints are valid: one gives symbol name, - the other the offending symbol type. */ - complain (&unknown_sym_complaint, name); - complain (&unknown_st_complaint, sh.st); - cur_sdx++; - continue; - } - /* Use this gdb symbol */ - ADD_PSYMBOL_TO_LIST (name, strlen (name), - VAR_NAMESPACE, class, - objfile->static_psymbols, sh.value, - psymtab_language, objfile); - skip: - cur_sdx++; /* Go to next file symbol */ - } - - /* Now do enter the external symbols. */ - ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset]; - cur_sdx = fdr_to_pst[f_idx].n_globals; - PST_PRIVATE (save_pst)->extern_count = cur_sdx; - PST_PRIVATE (save_pst)->extern_tab = ext_ptr; - for (; --cur_sdx >= 0; ext_ptr++) - { - enum address_class class; - SYMR *psh; - char *name; - CORE_ADDR svalue; - - if (ext_ptr->ifd != f_idx) - abort (); - psh = &ext_ptr->asym; - - /* Do not add undefined symbols to the partial symbol table. */ - if (psh->sc == scUndefined || psh->sc == scNil) - continue; - - svalue = psh->value; - switch (psh->sc) - { - case scText: - svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT); - break; - case scData: - case scSData: - case scRData: - case scPData: - case scXData: - svalue += ANOFFSET (section_offsets, SECT_OFF_DATA); - break; - case scBss: - case scSBss: - svalue += ANOFFSET (section_offsets, SECT_OFF_BSS); - break; - } - - switch (psh->st) - { - case stNil: - /* These are generated for static symbols in .o files, - ignore them. */ - continue; - case stProc: - case stStaticProc: - /* External procedure symbols have been entered - into the minimal symbol table in pass 2 above. - Ignore them, as parse_external will ignore them too. */ - continue; - case stLabel: - class = LOC_LABEL; - break; - default: - complain (&unknown_ext_complaint, - debug_info->ssext + psh->iss); - /* Fall through, pretend it's global. */ - case stGlobal: - class = LOC_STATIC; - break; - } - name = debug_info->ssext + psh->iss; - ADD_PSYMBOL_ADDR_TO_LIST (name, strlen (name), - VAR_NAMESPACE, class, - objfile->global_psymbols, - svalue, - psymtab_language, objfile); - } - } - - /* Link pst to FDR. end_psymtab returns NULL if the psymtab was - empty and put on the free list. */ - fdr_to_pst[f_idx].pst = end_psymtab (save_pst, - psymtab_include_list, includes_used, - -1, save_pst->texthigh, - dependency_list, dependencies_used); - if (objfile->ei.entry_point >= save_pst->textlow && - objfile->ei.entry_point < save_pst->texthigh) - { - objfile->ei.entry_file_lowpc = save_pst->textlow; - objfile->ei.entry_file_highpc = save_pst->texthigh; - } - } - - /* Now scan the FDRs for dependencies */ - for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) - { - fh = f_idx + debug_info->fdr; - pst = fdr_to_pst[f_idx].pst; - - if (pst == (struct partial_symtab *)NULL) - continue; - - /* This should catch stabs-in-ecoff. */ - if (fh->crfd <= 1) - continue; - - /* Skip the first file indirect entry as it is a self dependency - for source files or a reverse .h -> .c dependency for header files. */ - pst->number_of_dependencies = 0; - pst->dependencies = - ((struct partial_symtab **) - obstack_alloc (&objfile->psymbol_obstack, - ((fh->crfd - 1) - * sizeof (struct partial_symtab *)))); - for (s_idx = 1; s_idx < fh->crfd; s_idx++) - { - RFDT rh; - - (*swap_rfd_in) (cur_bfd, - ((char *) debug_info->external_rfd - + (fh->rfdBase + s_idx) * external_rfd_size), - &rh); - if (rh < 0 || rh >= hdr->ifdMax) - { - complain (&bad_file_number_complaint, rh); - continue; - } - - /* Skip self dependencies of header files. */ - if (rh == f_idx) - continue; - - /* Do not add to dependeny list if psymtab was empty. */ - if (fdr_to_pst[rh].pst == (struct partial_symtab *)NULL) - continue; - pst->dependencies[pst->number_of_dependencies++] = fdr_to_pst[rh].pst; - } - } - - /* Remove the dummy psymtab created for -O3 images above, if it is - still empty, to enable the detection of stripped executables. */ - if (objfile->psymtabs->next == NULL - && objfile->psymtabs->number_of_dependencies == 0 - && objfile->psymtabs->n_global_syms == 0 - && objfile->psymtabs->n_static_syms == 0) - objfile->psymtabs = NULL; - do_cleanups (old_chain); -} - -/* If the current psymbol has an enumerated type, we need to add - all the the enum constants to the partial symbol table. */ - -static void -handle_psymbol_enumerators (objfile, fh, stype) - struct objfile *objfile; - FDR *fh; - int stype; -{ - const bfd_size_type external_sym_size = debug_swap->external_sym_size; - void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) - = debug_swap->swap_sym_in; - char *ext_sym = ((char *) debug_info->external_sym - + ((fh->isymBase + cur_sdx + 1) * external_sym_size)); - SYMR sh; - TIR tir; - - switch (stype) - { - case stEnum: - break; - - case stBlock: - /* It is an enumerated type if the next symbol entry is a stMember - and its auxiliary index is indexNil or its auxiliary entry - is a plain btNil or btVoid. */ - (*swap_sym_in) (cur_bfd, ext_sym, &sh); - if (sh.st != stMember) - return; - - if (sh.index == indexNil) - break; - (*debug_swap->swap_tir_in) (fh->fBigendian, - &(debug_info->external_aux - + fh->iauxBase + sh.index)->a_ti, - &tir); - if ((tir.bt != btNil && tir.bt != btVoid) || tir.tq0 != tqNil) - return; - break; - - default: - return; - } - - for (;;) - { - char *name; - - (*swap_sym_in) (cur_bfd, ext_sym, &sh); - if (sh.st != stMember) - break; - name = debug_info->ss + cur_fdr->issBase + sh.iss; - - /* Note that the value doesn't matter for enum constants - in psymtabs, just in symtabs. */ - ADD_PSYMBOL_TO_LIST (name, strlen (name), - VAR_NAMESPACE, LOC_CONST, - objfile->static_psymbols, 0, - psymtab_language, objfile); - ext_sym += external_sym_size; - } -} - -static char * -mdebug_next_symbol_text () -{ - SYMR sh; - - cur_sdx++; - (*debug_swap->swap_sym_in) (cur_bfd, - ((char *) debug_info->external_sym - + ((cur_fdr->isymBase + cur_sdx) - * debug_swap->external_sym_size)), - &sh); - return debug_info->ss + cur_fdr->issBase + sh.iss; -} - -/* Ancillary function to psymtab_to_symtab(). Does all the work - for turning the partial symtab PST into a symtab, recurring - first on all dependent psymtabs. The argument FILENAME is - only passed so we can see in debug stack traces what file - is being read. - - This function has a split personality, based on whether the - symbol table contains ordinary ecoff symbols, or stabs-in-ecoff. - The flow of control and even the memory allocation differs. FIXME. */ - -static void -psymtab_to_symtab_1 (pst, filename) - struct partial_symtab *pst; - char *filename; -{ - bfd_size_type external_sym_size; - bfd_size_type external_pdr_size; - void (*swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)); - void (*swap_pdr_in) PARAMS ((bfd *, PTR, PDR *)); - int i; - struct symtab *st; - FDR *fh; - struct linetable *lines; - - if (pst->readin) - return; - pst->readin = 1; - - /* Read in all partial symbtabs on which this one is dependent. - NOTE that we do have circular dependencies, sigh. We solved - that by setting pst->readin before this point. */ - - for (i = 0; i < pst->number_of_dependencies; i++) - if (!pst->dependencies[i]->readin) - { - /* Inform about additional files 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); - } - /* We only pass the filename for debug purposes */ - psymtab_to_symtab_1 (pst->dependencies[i], - pst->dependencies[i]->filename); - } - - /* Do nothing if this is a dummy psymtab. */ - - if (pst->n_global_syms == 0 && pst->n_static_syms == 0 - && pst->textlow == 0 && pst->texthigh == 0) - return; - - /* Now read the symbols for this symtab */ - - cur_bfd = CUR_BFD (pst); - debug_swap = DEBUG_SWAP (pst); - debug_info = DEBUG_INFO (pst); - pending_list = PENDING_LIST (pst); - external_sym_size = debug_swap->external_sym_size; - external_pdr_size = debug_swap->external_pdr_size; - swap_sym_in = debug_swap->swap_sym_in; - swap_pdr_in = debug_swap->swap_pdr_in; - current_objfile = pst->objfile; - cur_fd = FDR_IDX (pst); - fh = ((cur_fd == -1) - ? (FDR *) NULL - : debug_info->fdr + cur_fd); - cur_fdr = fh; - - /* See comment in parse_partial_symbols about the @stabs sentinel. */ - processing_gcc_compilation = 0; - if (fh != (FDR *) NULL && fh->csym >= 2) - { - SYMR sh; - - (*swap_sym_in) (cur_bfd, - ((char *) debug_info->external_sym - + (fh->isymBase + 1) * external_sym_size), - &sh); - if (STREQ (debug_info->ss + fh->issBase + sh.iss, - stabs_symbol)) - { - /* We indicate that this is a GCC compilation so that certain - features will be enabled in stabsread/dbxread. */ - processing_gcc_compilation = 2; - } - } - - if (processing_gcc_compilation != 0) - { - char *pdr_ptr; - char *pdr_end; - int first_pdr; - unsigned long first_off = 0; - - /* This symbol table contains stabs-in-ecoff entries. */ - - /* Parse local symbols first */ - - if (fh->csym <= 2) /* FIXME, this blows psymtab->symtab ptr */ - { - current_objfile = NULL; - return; - } - for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++) - { - SYMR sh; - char *name; - CORE_ADDR valu; - - (*swap_sym_in) (cur_bfd, - (((char *) debug_info->external_sym) - + (fh->isymBase + cur_sdx) * external_sym_size), - &sh); - name = debug_info->ss + fh->issBase + sh.iss; - valu = sh.value; - if (ECOFF_IS_STAB (&sh)) - { - int type_code = ECOFF_UNMARK_STAB (sh.index); - - /* We should never get non N_STAB symbols here, but they - should be harmless, so keep process_one_symbol from - complaining about them. */ - if (type_code & N_STAB) - { - process_one_symbol (type_code, 0, valu, name, - pst->section_offsets, pst->objfile); - } - if (type_code == N_FUN) - { - /* Make up special symbol to contain - procedure specific info */ - struct mips_extra_func_info *e = - ((struct mips_extra_func_info *) - obstack_alloc (¤t_objfile->symbol_obstack, - sizeof (struct mips_extra_func_info))); - struct symbol *s = new_symbol (MIPS_EFI_SYMBOL_NAME); - SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE; - SYMBOL_CLASS (s) = LOC_CONST; - SYMBOL_TYPE (s) = builtin_type_void; - SYMBOL_VALUE (s) = (long) e; - add_symbol_to_list (s, &local_symbols); - } - } - else if (sh.st == stLabel) - { - if (sh.index == indexNil) - { - /* This is what the gcc2_compiled and __gnu_compiled_* - show up as. So don't complain. */ - ; - } - else - /* Handle encoded stab line number. */ - record_line (current_subfile, sh.index, valu); - } - else if (sh.st == stProc || sh.st == stStaticProc - || sh.st == stStatic || sh.st == stEnd) - /* These are generated by gcc-2.x, do not complain */ - ; - else - complain (&stab_unknown_complaint, name); - } - st = end_symtab (pst->texthigh, 0, 0, pst->objfile, SECT_OFF_TEXT); - end_stabs (); - - /* Sort the symbol table now, we are done adding symbols to it. - We must do this before parse_procedure calls lookup_symbol. */ - sort_symtab_syms (st); - - /* There used to be a call to sort_blocks here, but this should not - be necessary for stabs symtabs. And as sort_blocks modifies the - start address of the GLOBAL_BLOCK to the FIRST_LOCAL_BLOCK, - it did the wrong thing if the first procedure in a file was - generated via asm statements. */ - - /* Fill in procedure info next. */ - first_pdr = 1; - pdr_ptr = ((char *) debug_info->external_pdr - + fh->ipdFirst * external_pdr_size); - pdr_end = pdr_ptr + fh->cpd * external_pdr_size; - for (; pdr_ptr < pdr_end; pdr_ptr += external_pdr_size) - { - PDR pr; - - (*swap_pdr_in) (cur_bfd, pdr_ptr, &pr); - if (first_pdr) - { - first_off = pr.adr; - first_pdr = 0; - } - parse_procedure (&pr, st, first_off, pst); - } - } - else - { - /* This symbol table contains ordinary ecoff entries. */ - - /* FIXME: doesn't use pst->section_offsets. */ - - int f_max; - int maxlines; - EXTR *ext_ptr; - - /* How many symbols will we need */ - /* FIXME, this does not count enum values. */ - f_max = pst->n_global_syms + pst->n_static_syms; - if (fh == 0) - { - maxlines = 0; - st = new_symtab ("unknown", f_max, 0, pst->objfile); - } - else - { - f_max += fh->csym + fh->cpd; - maxlines = 2 * fh->cline; - st = new_symtab (pst->filename, 2 * f_max, maxlines, pst->objfile); - - /* The proper language was already determined when building - the psymtab, use it. */ - st->language = PST_PRIVATE (pst)->pst_language; - } - - psymtab_language = st->language; - - lines = LINETABLE (st); - - /* Get a new lexical context */ - - push_parse_stack (); - top_stack->cur_st = st; - top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (st), - STATIC_BLOCK); - BLOCK_START (top_stack->cur_block) = pst->textlow; - BLOCK_END (top_stack->cur_block) = 0; - top_stack->blocktype = stFile; - top_stack->maxsyms = 2 * f_max; - top_stack->cur_type = 0; - top_stack->procadr = 0; - top_stack->numargs = 0; - - if (fh) - { - char *sym_ptr; - char *sym_end; - - /* Parse local symbols first */ - sym_ptr = ((char *) debug_info->external_sym - + fh->isymBase * external_sym_size); - sym_end = sym_ptr + fh->csym * external_sym_size; - while (sym_ptr < sym_end) - { - SYMR sh; - int c; - - (*swap_sym_in) (cur_bfd, sym_ptr, &sh); - c = parse_symbol (&sh, - debug_info->external_aux + fh->iauxBase, - sym_ptr, fh->fBigendian, pst->section_offsets); - sym_ptr += c * external_sym_size; - } - - /* Linenumbers. At the end, check if we can save memory. - parse_lines has to look ahead an arbitrary number of PDR - structures, so we swap them all first. */ - if (fh->cpd > 0) - { - PDR *pr_block; - struct cleanup *old_chain; - char *pdr_ptr; - char *pdr_end; - PDR *pdr_in; - PDR *pdr_in_end; - - pr_block = (PDR *) xmalloc (fh->cpd * sizeof (PDR)); - - old_chain = make_cleanup (free, pr_block); - - pdr_ptr = ((char *) debug_info->external_pdr - + fh->ipdFirst * external_pdr_size); - pdr_end = pdr_ptr + fh->cpd * external_pdr_size; - pdr_in = pr_block; - for (; - pdr_ptr < pdr_end; - pdr_ptr += external_pdr_size, pdr_in++) - (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in); - - parse_lines (fh, pr_block, lines, maxlines, pst); - if (lines->nitems < fh->cline) - lines = shrink_linetable (lines); - - /* Fill in procedure info next. */ - pdr_in = pr_block; - pdr_in_end = pdr_in + fh->cpd; - for (; pdr_in < pdr_in_end; pdr_in++) - parse_procedure (pdr_in, 0, pr_block->adr, pst); - - do_cleanups (old_chain); - } - } - - LINETABLE (st) = lines; - - /* .. and our share of externals. - XXX use the global list to speed up things here. how? - FIXME, Maybe quit once we have found the right number of ext's? */ - top_stack->cur_st = st; - top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (top_stack->cur_st), - GLOBAL_BLOCK); - top_stack->blocktype = stFile; - top_stack->maxsyms - = (debug_info->symbolic_header.isymMax - + debug_info->symbolic_header.ipdMax - + debug_info->symbolic_header.iextMax); - - ext_ptr = PST_PRIVATE (pst)->extern_tab; - for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++) - parse_external (ext_ptr, fh->fBigendian, pst->section_offsets); - - /* If there are undefined symbols, tell the user. - The alpha has an undefined symbol for every symbol that is - from a shared library, so tell the user only if verbose is on. */ - if (info_verbose && n_undef_symbols) - { - printf_filtered ("File %s contains %d unresolved references:", - st->filename, n_undef_symbols); - printf_filtered ("\n\t%4d variables\n\t%4d procedures\n\t%4d labels\n", - n_undef_vars, n_undef_procs, n_undef_labels); - n_undef_symbols = n_undef_labels = n_undef_vars = n_undef_procs = 0; - - } - pop_parse_stack (); - - st->primary = 1; - - /* Sort the symbol table now, we are done adding symbols to it.*/ - sort_symtab_syms (st); - - sort_blocks (st); - } - - /* Now link the psymtab and the symtab. */ - pst->symtab = st; - - current_objfile = NULL; -} - -/* Ancillary parsing procedures. */ - -/* Return 1 if the symbol pointed to by SH has a cross reference - to an opaque aggregate type, else 0. */ - -static int -has_opaque_xref (fh, sh) - FDR *fh; - SYMR *sh; -{ - TIR tir; - union aux_ext *ax; - RNDXR rn[1]; - unsigned int rf; - - if (sh->index == indexNil) - return 0; - - ax = debug_info->external_aux + fh->iauxBase + sh->index; - (*debug_swap->swap_tir_in) (fh->fBigendian, &ax->a_ti, &tir); - if (tir.bt != btStruct && tir.bt != btUnion && tir.bt != btEnum) - return 0; - - ax++; - (*debug_swap->swap_rndx_in) (fh->fBigendian, &ax->a_rndx, rn); - if (rn->rfd == 0xfff) - rf = AUX_GET_ISYM (fh->fBigendian, ax + 1); - else - rf = rn->rfd; - if (rf != -1) - return 0; - return 1; -} - -/* Lookup the type at relative index RN. Return it in TPP - if found and in any event come up with its name PNAME. - BIGEND says whether aux symbols are big-endian or not (from fh->fBigendian). - Return value says how many aux symbols we ate. */ - -static int -cross_ref (fd, ax, tpp, type_code, pname, bigend, sym_name) - int fd; - union aux_ext *ax; - struct type **tpp; - enum type_code type_code; /* Use to alloc new type if none is found. */ - char **pname; - int bigend; - char *sym_name; -{ - RNDXR rn[1]; - unsigned int rf; - int result = 1; - FDR *fh; - char *esh; - SYMR sh; - int xref_fd; - struct mdebug_pending *pend; - - *tpp = (struct type *)NULL; - - (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, rn); - - /* Escape index means 'the next one' */ - if (rn->rfd == 0xfff) - { - result++; - rf = AUX_GET_ISYM (bigend, ax + 1); - } - else - { - rf = rn->rfd; - } - - /* mips cc uses a rf of -1 for opaque struct definitions. - Set TYPE_FLAG_STUB for these types so that check_stub_type will - resolve them if the struct gets defined in another compilation unit. */ - if (rf == -1) - { - *pname = ""; - *tpp = init_type (type_code, 0, 0, (char *) NULL, current_objfile); - TYPE_FLAGS (*tpp) |= TYPE_FLAG_STUB; - return result; - } - - /* mips cc uses an escaped rn->index of 0 for struct return types - of procedures that were compiled without -g. These will always remain - undefined. */ - if (rn->rfd == 0xfff && rn->index == 0) - { - *pname = ""; - return result; - } - - /* Find the relative file descriptor and the symbol in it. */ - fh = get_rfd (fd, rf); - xref_fd = fh - debug_info->fdr; - - if (rn->index >= fh->csym) - { - /* File indirect entry is corrupt. */ - *pname = ""; - complain (&bad_rfd_entry_complaint, - sym_name, xref_fd, rn->index); - return result; - } - - /* If we have processed this symbol then we left a forwarding - pointer to the type in the pending list. If not, we`ll put - it in a list of pending types, to be processed later when - the file will be. In any event, we collect the name for the - type here. */ - - esh = ((char *) debug_info->external_sym - + ((fh->isymBase + rn->index) - * debug_swap->external_sym_size)); - (*debug_swap->swap_sym_in) (cur_bfd, esh, &sh); - - /* Make sure that this type of cross reference can be handled. */ - if ((sh.sc != scInfo - || (sh.st != stBlock && sh.st != stTypedef && sh.st != stIndirect - && sh.st != stStruct && sh.st != stUnion - && sh.st != stEnum)) - && (sh.sc != scCommon || sh.st != stBlock)) - { - /* File indirect entry is corrupt. */ - *pname = ""; - complain (&bad_rfd_entry_complaint, - sym_name, xref_fd, rn->index); - return result; - } - - *pname = debug_info->ss + fh->issBase + sh.iss; - - pend = is_pending_symbol (fh, esh); - if (pend) - *tpp = pend->t; - else - { - /* We have not yet seen this type. */ - - if ((sh.iss == 0 && sh.st == stTypedef) || sh.st == stIndirect) - { - TIR tir; - - /* alpha cc puts out a stTypedef with a sh.iss of zero for - two cases: - a) forward declarations of structs/unions/enums which are not - defined in this compilation unit. - For these the type will be void. This is a bad design decision - as cross referencing across compilation units is impossible - due to the missing name. - b) forward declarations of structs/unions/enums which are defined - later in this file or in another file in the same compilation - unit. Irix5 cc uses a stIndirect symbol for this. - Simply cross reference those again to get the true type. - The forward references are not entered in the pending list and - in the symbol table. */ - - (*debug_swap->swap_tir_in) (bigend, - &(debug_info->external_aux - + fh->iauxBase + sh.index)->a_ti, - &tir); - if (tir.tq0 != tqNil) - complain (&illegal_forward_tq0_complaint, sym_name); - switch (tir.bt) - { - case btVoid: - *tpp = init_type (type_code, 0, 0, (char *) NULL, - current_objfile); - *pname = ""; - break; - - case btStruct: - case btUnion: - case btEnum: - cross_ref (xref_fd, - (debug_info->external_aux - + fh->iauxBase + sh.index + 1), - tpp, type_code, pname, - fh->fBigendian, sym_name); - break; - - default: - complain (&illegal_forward_bt_complaint, tir.bt, sym_name); - *tpp = init_type (type_code, 0, 0, (char *) NULL, - current_objfile); - break; - } - return result; - } - else if (sh.st == stTypedef) - { - /* Parse the type for a normal typedef. This might recursively call - cross_ref till we get a non typedef'ed type. - FIXME: This is not correct behaviour, but gdb currently - cannot handle typedefs without type copying. But type copying is - impossible as we might have mutual forward references between - two files and the copied type would not get filled in when - we later parse its definition. */ - *tpp = parse_type (xref_fd, - debug_info->external_aux + fh->iauxBase, - sh.index, - (int *)NULL, - fh->fBigendian, - debug_info->ss + fh->issBase + sh.iss); - } - else - { - /* Cross reference to a struct/union/enum which is defined - in another file in the same compilation unit but that file - has not been parsed yet. - Initialize the type only, it will be filled in when - it's definition is parsed. */ - *tpp = init_type (type_code, 0, 0, (char *) NULL, current_objfile); - } - add_pending (fh, esh, *tpp); - } - - /* We used one auxent normally, two if we got a "next one" rf. */ - return result; -} - - -/* Quick&dirty lookup procedure, to avoid the MI ones that require - keeping the symtab sorted */ - -static struct symbol * -mylookup_symbol (name, block, namespace, class) - char *name; - register struct block *block; - enum namespace namespace; - enum address_class class; -{ - register int bot, top, inc; - register struct symbol *sym; - - bot = 0; - top = BLOCK_NSYMS (block); - inc = name[0]; - while (bot < top) - { - sym = BLOCK_SYM (block, bot); - if (SYMBOL_NAME (sym)[0] == inc - && SYMBOL_NAMESPACE (sym) == namespace - && SYMBOL_CLASS (sym) == class - && strcmp (SYMBOL_NAME (sym), name) == 0) - return sym; - bot++; - } - block = BLOCK_SUPERBLOCK (block); - if (block) - return mylookup_symbol (name, block, namespace, class); - return 0; -} - - -/* Add a new symbol S to a block B. - Infrequently, we will need to reallocate the block to make it bigger. - We only detect this case when adding to top_stack->cur_block, since - that's the only time we know how big the block is. FIXME. */ - -static void -add_symbol (s, b) - struct symbol *s; - struct block *b; -{ - int nsyms = BLOCK_NSYMS (b)++; - struct block *origb; - struct parse_stack *stackp; - - if (b == top_stack->cur_block && - nsyms >= top_stack->maxsyms) - { - complain (&block_overflow_complaint, SYMBOL_NAME (s)); - /* In this case shrink_block is actually grow_block, since - BLOCK_NSYMS(b) is larger than its current size. */ - origb = b; - b = shrink_block (top_stack->cur_block, top_stack->cur_st); - - /* Now run through the stack replacing pointers to the - original block. shrink_block has already done this - for the blockvector and BLOCK_FUNCTION. */ - for (stackp = top_stack; stackp; stackp = stackp->next) - { - if (stackp->cur_block == origb) - { - stackp->cur_block = b; - stackp->maxsyms = BLOCK_NSYMS (b); - } - } - } - BLOCK_SYM (b, nsyms) = s; -} - -/* Add a new block B to a symtab S */ - -static void -add_block (b, s) - struct block *b; - struct symtab *s; -{ - struct blockvector *bv = BLOCKVECTOR (s); - - bv = (struct blockvector *) xrealloc ((PTR) bv, - (sizeof (struct blockvector) - + BLOCKVECTOR_NBLOCKS (bv) - * sizeof (bv->block))); - if (bv != BLOCKVECTOR (s)) - BLOCKVECTOR (s) = bv; - - BLOCKVECTOR_BLOCK (bv, BLOCKVECTOR_NBLOCKS (bv)++) = b; -} - -/* Add a new linenumber entry (LINENO,ADR) to a linevector LT. - MIPS' linenumber encoding might need more than one byte - to describe it, LAST is used to detect these continuation lines. - - Combining lines with the same line number seems like a bad idea. - E.g: There could be a line number entry with the same line number after the - prologue and GDB should not ignore it (this is a better way to find - a prologue than mips_skip_prologue). - But due to the compressed line table format there are line number entries - for the same line which are needed to bridge the gap to the next - line number entry. These entries have a bogus address info with them - and we are unable to tell them from intended duplicate line number - entries. - This is another reason why -ggdb debugging format is preferable. */ - -static int -add_line (lt, lineno, adr, last) - struct linetable *lt; - int lineno; - CORE_ADDR adr; - int last; -{ - /* DEC c89 sometimes produces zero linenos which confuse gdb. - Change them to something sensible. */ - if (lineno == 0) - lineno = 1; - if (last == 0) - last = -2; /* make sure we record first line */ - - if (last == lineno) /* skip continuation lines */ - return lineno; - - lt->item[lt->nitems].line = lineno; - lt->item[lt->nitems++].pc = adr << 2; - return lineno; -} - -/* Sorting and reordering procedures */ - -/* Blocks with a smaller low bound should come first */ - -static int -compare_blocks (arg1, arg2) - const PTR arg1; - const PTR arg2; -{ - register int addr_diff; - struct block **b1 = (struct block **) arg1; - struct block **b2 = (struct block **) arg2; - - addr_diff = (BLOCK_START ((*b1))) - (BLOCK_START ((*b2))); - if (addr_diff == 0) - return (BLOCK_END ((*b2))) - (BLOCK_END ((*b1))); - return addr_diff; -} - -/* Sort the blocks of a symtab S. - Reorder the blocks in the blockvector by code-address, - as required by some MI search routines */ - -static void -sort_blocks (s) - struct symtab *s; -{ - struct blockvector *bv = BLOCKVECTOR (s); - - if (BLOCKVECTOR_NBLOCKS (bv) <= 2) - { - /* Cosmetic */ - if (BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) == 0) - BLOCK_START (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) = 0; - if (BLOCK_END (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) == 0) - BLOCK_START (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) = 0; - return; - } - /* - * This is very unfortunate: normally all functions are compiled in - * the order they are found, but if the file is compiled -O3 things - * are very different. It would be nice to find a reliable test - * to detect -O3 images in advance. - */ - if (BLOCKVECTOR_NBLOCKS (bv) > 3) - qsort (&BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK), - BLOCKVECTOR_NBLOCKS (bv) - FIRST_LOCAL_BLOCK, - sizeof (struct block *), - compare_blocks); - - { - register CORE_ADDR high = 0; - register int i, j = BLOCKVECTOR_NBLOCKS (bv); - - for (i = FIRST_LOCAL_BLOCK; i < j; i++) - if (high < BLOCK_END (BLOCKVECTOR_BLOCK (bv, i))) - high = BLOCK_END (BLOCKVECTOR_BLOCK (bv, i)); - BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) = high; - } - - BLOCK_START (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) = - BLOCK_START (BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK)); - - BLOCK_START (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) = - BLOCK_START (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)); - BLOCK_END (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) = - BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)); -} - - -/* Constructor/restructor/destructor procedures */ - -/* Allocate a new symtab for NAME. Needs an estimate of how many symbols - MAXSYMS and linenumbers MAXLINES we'll put in it */ - -static struct symtab * -new_symtab (name, maxsyms, maxlines, objfile) - char *name; - int maxsyms; - int maxlines; - struct objfile *objfile; -{ - struct symtab *s = allocate_symtab (name, objfile); - - LINETABLE (s) = new_linetable (maxlines); - - /* All symtabs must have at least two blocks */ - BLOCKVECTOR (s) = new_bvect (2); - BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK) = new_block (maxsyms); - BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK) = new_block (maxsyms); - BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)) = - BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); - - s->free_code = free_linetable; - - return (s); -} - -/* Allocate a new partial_symtab NAME */ - -static struct partial_symtab * -new_psymtab (name, objfile, section_offsets) - char *name; - struct objfile *objfile; - struct section_offsets *section_offsets; -{ - struct partial_symtab *psymtab; - - psymtab = allocate_psymtab (name, objfile); - psymtab->section_offsets = section_offsets; - - /* Keep a backpointer to the file's symbols */ - - psymtab->read_symtab_private = ((char *) - obstack_alloc (&objfile->psymbol_obstack, - sizeof (struct symloc))); - memset ((PTR) psymtab->read_symtab_private, 0, sizeof (struct symloc)); - CUR_BFD (psymtab) = cur_bfd; - DEBUG_SWAP (psymtab) = debug_swap; - DEBUG_INFO (psymtab) = debug_info; - PENDING_LIST (psymtab) = pending_list; - - /* The way to turn this into a symtab is to call... */ - psymtab->read_symtab = mdebug_psymtab_to_symtab; - return (psymtab); -} - - -/* Allocate a linetable array of the given SIZE. Since the struct - already includes one item, we subtract one when calculating the - proper size to allocate. */ - -static struct linetable * -new_linetable (size) - int size; -{ - struct linetable *l; - - size = (size - 1) * sizeof (l->item) + sizeof (struct linetable); - l = (struct linetable *) xmalloc (size); - l->nitems = 0; - return l; -} - -/* Oops, too big. Shrink it. This was important with the 2.4 linetables, - I am not so sure about the 3.4 ones. - - Since the struct linetable already includes one item, we subtract one when - calculating the proper size to allocate. */ - -static struct linetable * -shrink_linetable (lt) - struct linetable *lt; -{ - - return (struct linetable *) xrealloc ((PTR) lt, - (sizeof (struct linetable) - + ((lt->nitems - 1) - * sizeof (lt->item)))); -} - -/* Allocate and zero a new blockvector of NBLOCKS blocks. */ - -static struct blockvector * -new_bvect (nblocks) - int nblocks; -{ - struct blockvector *bv; - int size; - - size = sizeof (struct blockvector) + nblocks * sizeof (struct block *); - bv = (struct blockvector *) xzalloc (size); - - BLOCKVECTOR_NBLOCKS (bv) = nblocks; - - return bv; -} - -/* Allocate and zero a new block of MAXSYMS symbols */ - -static struct block * -new_block (maxsyms) - int maxsyms; -{ - int size = sizeof (struct block) + (maxsyms - 1) * sizeof (struct symbol *); - - return (struct block *) xzalloc (size); -} - -/* Ooops, too big. Shrink block B in symtab S to its minimal size. - Shrink_block can also be used by add_symbol to grow a block. */ - -static struct block * -shrink_block (b, s) - struct block *b; - struct symtab *s; -{ - struct block *new; - struct blockvector *bv = BLOCKVECTOR (s); - int i; - - /* Just reallocate it and fix references to the old one */ - - new = (struct block *) xrealloc ((PTR) b, - (sizeof (struct block) - + ((BLOCK_NSYMS (b) - 1) - * sizeof (struct symbol *)))); - - /* Should chase pointers to old one. Fortunately, that`s just - the block`s function and inferior blocks */ - if (BLOCK_FUNCTION (new) && SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) == b) - SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) = new; - for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++) - if (BLOCKVECTOR_BLOCK (bv, i) == b) - BLOCKVECTOR_BLOCK (bv, i) = new; - else if (BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) == b) - BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) = new; - return new; -} - -/* Create a new symbol with printname NAME */ - -static struct symbol * -new_symbol (name) - char *name; -{ - struct symbol *s = ((struct symbol *) - obstack_alloc (¤t_objfile->symbol_obstack, - sizeof (struct symbol))); - - memset ((PTR) s, 0, sizeof (*s)); - SYMBOL_NAME (s) = name; - SYMBOL_LANGUAGE (s) = psymtab_language; - SYMBOL_INIT_DEMANGLED_NAME (s, ¤t_objfile->symbol_obstack); - return s; -} - -/* Create a new type with printname NAME */ - -static struct type * -new_type (name) - char *name; -{ - struct type *t; - - t = alloc_type (current_objfile); - TYPE_NAME (t) = name; - TYPE_CPLUS_SPECIFIC (t) = (struct cplus_struct_type *) &cplus_struct_default; - return t; -} - -/* Read ECOFF debugging information from a BFD section. This is - called from elfread.c. It parses the section into a - ecoff_debug_info struct, and then lets the rest of the file handle - it as normal. */ - -void -elfmdebug_build_psymtabs (objfile, swap, sec, section_offsets) - struct objfile *objfile; - const struct ecoff_debug_swap *swap; - asection *sec; - struct section_offsets *section_offsets; -{ - bfd *abfd = objfile->obfd; - struct ecoff_debug_info *info; - - info = ((struct ecoff_debug_info *) - obstack_alloc (&objfile->psymbol_obstack, - sizeof (struct ecoff_debug_info))); - - if (!(*swap->read_debug_info) (abfd, sec, info)) - error ("Error reading ECOFF debugging information: %s", - bfd_errmsg (bfd_get_error ())); - - mdebug_build_psymtabs (objfile, swap, info, section_offsets); -} - - -/* Things used for calling functions in the inferior. - These functions are exported to our companion - mips-tdep.c file and are here because they play - with the symbol-table explicitly. */ - -/* Sigtramp: make sure we have all the necessary information - about the signal trampoline code. Since the official code - from MIPS does not do so, we make up that information ourselves. - If they fix the library (unlikely) this code will neutralize itself. */ - -/* 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. */ - -void -fixup_sigtramp () -{ - struct symbol *s; - struct symtab *st; - struct block *b, *b0 = NULL; - - sigtramp_address = -1; - - /* We have to handle the following cases here: - a) The Mips library has a sigtramp label within sigvec. - b) Irix has a _sigtramp which we want to use, but it also has sigvec. */ - s = lookup_symbol ("sigvec", 0, VAR_NAMESPACE, 0, NULL); - if (s != 0) - { - b0 = SYMBOL_BLOCK_VALUE (s); - s = lookup_symbol ("sigtramp", b0, VAR_NAMESPACE, 0, NULL); - } - if (s == 0) - { - /* No sigvec or no sigtramp inside sigvec, try _sigtramp. */ - s = lookup_symbol ("_sigtramp", 0, VAR_NAMESPACE, 0, NULL); - } - - /* But maybe this program uses its own version of sigvec */ - if (s == 0) - return; - - /* Did we or MIPSco fix the library ? */ - if (SYMBOL_CLASS (s) == LOC_BLOCK) - { - sigtramp_address = BLOCK_START (SYMBOL_BLOCK_VALUE (s)); - sigtramp_end = BLOCK_END (SYMBOL_BLOCK_VALUE (s)); - return; - } - - sigtramp_address = SYMBOL_VALUE (s); - sigtramp_end = sigtramp_address + 0x88; /* black magic */ - - /* But what symtab does it live in ? */ - st = find_pc_symtab (SYMBOL_VALUE (s)); - - /* - * Ok, there goes the fix: turn it into a procedure, with all the - * needed info. Note we make it a nested procedure of sigvec, - * which is the way the (assembly) code is actually written. - */ - SYMBOL_NAMESPACE (s) = VAR_NAMESPACE; - SYMBOL_CLASS (s) = LOC_BLOCK; - SYMBOL_TYPE (s) = init_type (TYPE_CODE_FUNC, 4, 0, (char *) NULL, - st->objfile); - TYPE_TARGET_TYPE (SYMBOL_TYPE (s)) = builtin_type_void; - - /* Need a block to allocate MIPS_EFI_SYMBOL_NAME in */ - b = new_block (1); - SYMBOL_BLOCK_VALUE (s) = b; - BLOCK_START (b) = sigtramp_address; - BLOCK_END (b) = sigtramp_end; - BLOCK_FUNCTION (b) = s; - BLOCK_SUPERBLOCK (b) = BLOCK_SUPERBLOCK (b0); - add_block (b, st); - sort_blocks (st); - - /* Make a MIPS_EFI_SYMBOL_NAME entry for it */ - { - struct mips_extra_func_info *e = - ((struct mips_extra_func_info *) - xzalloc (sizeof (struct mips_extra_func_info))); - - e->numargs = 0; /* the kernel thinks otherwise */ - e->pdr.frameoffset = 32; - e->pdr.framereg = SP_REGNUM; - /* Note that setting pcreg is no longer strictly necessary as - mips_frame_saved_pc is now aware of signal handler frames. */ - e->pdr.pcreg = PC_REGNUM; - e->pdr.regmask = -2; - /* Offset to saved r31, in the sigtramp case the saved registers - are above the frame in the sigcontext. - We have 4 alignment bytes, 12 bytes for onstack, mask and pc, - 32 * 4 bytes for the general registers, 12 bytes for mdhi, mdlo, ownedfp - and 32 * 4 bytes for the floating point registers. */ - e->pdr.regoffset = 4 + 12 + 31 * 4; - e->pdr.fregmask = -1; - /* Offset to saved f30 (first saved *double* register). */ - e->pdr.fregoffset = 4 + 12 + 32 * 4 + 12 + 30 * 4; - e->pdr.isym = (long) s; - e->pdr.adr = sigtramp_address; - - current_objfile = st->objfile; /* Keep new_symbol happy */ - s = new_symbol (MIPS_EFI_SYMBOL_NAME); - SYMBOL_VALUE (s) = (long) e; - SYMBOL_NAMESPACE (s) = LABEL_NAMESPACE; - SYMBOL_CLASS (s) = LOC_CONST; - SYMBOL_TYPE (s) = builtin_type_void; - current_objfile = NULL; - } - - BLOCK_SYM (b, BLOCK_NSYMS (b)++) = s; -} - -void -_initialize_mdebugread () -{ - /* Missing basic types */ - - /* Is a "string" the way btString means it the same as TYPE_CODE_STRING? - FIXME. */ - mdebug_type_string = - init_type (TYPE_CODE_STRING, - TARGET_CHAR_BIT / TARGET_CHAR_BIT, - 0, "string", - (struct objfile *) NULL); - - mdebug_type_complex = - init_type (TYPE_CODE_ERROR, - TARGET_COMPLEX_BIT / TARGET_CHAR_BIT, - 0, "complex", - (struct objfile *) NULL); - mdebug_type_double_complex = - init_type (TYPE_CODE_ERROR, - TARGET_DOUBLE_COMPLEX_BIT / TARGET_CHAR_BIT, - 0, "double complex", - (struct objfile *) NULL); - - /* We use TYPE_CODE_INT to print these as integers. Does this do any - good? Would we be better off with TYPE_CODE_ERROR? Should - TYPE_CODE_ERROR print things in hex if it knows the size? */ - mdebug_type_fixed_dec = - init_type (TYPE_CODE_INT, - TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "fixed decimal", - (struct objfile *) NULL); - - mdebug_type_float_dec = - init_type (TYPE_CODE_ERROR, - TARGET_DOUBLE_BIT / TARGET_CHAR_BIT, - 0, "floating decimal", - (struct objfile *) NULL); -} diff --git a/gnu/usr.bin/gdb/gdb/mem-break.c b/gnu/usr.bin/gdb/gdb/mem-break.c deleted file mode 100644 index 2c7ba1f..0000000 --- a/gnu/usr.bin/gdb/gdb/mem-break.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Simulate breakpoints by patching locations in the target system, for GDB. - Copyright 1990, 1991 Free Software Foundation, Inc. - Contributed by Cygnus Support. Written by John Gilmore. - -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 "defs.h" - -#ifdef BREAKPOINT -/* This file is only useful if BREAKPOINT is set. If not, we punt. */ - -#include "symtab.h" -#include "breakpoint.h" -#include "inferior.h" -#include "target.h" - -/* 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 break_insn[] = BREAKPOINT; - -/* This is only to check that BREAKPOINT fits in BREAKPOINT_MAX bytes. */ - -static unsigned char check_break_insn_size[BREAKPOINT_MAX] = 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, - 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 - by the caller to be long enough to save sizeof BREAKPOINT bytes (this - is accomplished via BREAKPOINT_MAX). */ - -int -memory_insert_breakpoint (addr, contents_cache) - CORE_ADDR addr; - char *contents_cache; -{ - int val; - - val = target_read_memory (addr, contents_cache, sizeof break_insn); - - if (val == 0) - val = target_write_memory (addr, (char *)break_insn, sizeof break_insn); - - return val; -} - - -int -memory_remove_breakpoint (addr, contents_cache) - CORE_ADDR addr; - char *contents_cache; -{ - return target_write_memory (addr, contents_cache, sizeof break_insn); -} - - -/* FIXME: This is a hack and should depend on the debugging target. - See comment in breakpoint.c where this is used. */ - -int memory_breakpoint_size = sizeof (break_insn); - - -#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 */ -} - -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/gnu/usr.bin/gdb/gdb/minsyms.c b/gnu/usr.bin/gdb/gdb/minsyms.c deleted file mode 100644 index 743ba83..0000000 --- a/gnu/usr.bin/gdb/gdb/minsyms.c +++ /dev/null @@ -1,648 +0,0 @@ -/* GDB routines for manipulating the minimal symbol tables. - Copyright 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by Cygnus Support, using pieces from other GDB modules. - -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. */ - - -/* This file contains support routines for creating, manipulating, and - destroying minimal symbol tables. - - Minimal symbol tables are used to hold some very basic information about - all defined global symbols (text, data, bss, abs, etc). The only two - required pieces of information are the symbol's name and the address - associated with that symbol. - - In many cases, even if a file was compiled with no special options for - debugging at all, as long as was not stripped it will contain sufficient - information to build useful minimal symbol tables using this structure. - - Even when a file contains enough debugging information to build a full - symbol table, these minimal symbols are still useful for quickly mapping - between names and addresses, and vice versa. They are also sometimes used - to figure out what full symbol table entries need to be read in. */ - - -#include "defs.h" -#include -#include "symtab.h" -#include "bfd.h" -#include "symfile.h" -#include "objfiles.h" -#include "demangle.h" -#include "gdb-stabs.h" - -/* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE. - At the end, copy them all into one newly allocated location on an objfile's - symbol obstack. */ - -#define BUNCH_SIZE 127 - -struct msym_bunch -{ - struct msym_bunch *next; - struct minimal_symbol contents[BUNCH_SIZE]; -}; - -/* Bunch currently being filled up. - The next field points to chain of filled bunches. */ - -static struct msym_bunch *msym_bunch; - -/* Number of slots filled in current bunch. */ - -static int msym_bunch_index; - -/* Total number of minimal symbols recorded so far for the objfile. */ - -static int msym_count; - -/* Prototypes for local functions. */ - -static int -compare_minimal_symbols PARAMS ((const void *, const void *)); - -static int -compact_minimal_symbols PARAMS ((struct minimal_symbol *, int)); - -/* Look through all the current minimal symbol tables and find the first - minimal symbol that matches NAME. If OBJF is non-NULL, it specifies a - particular objfile and the search is limited to that objfile. Returns - a pointer to the minimal symbol that matches, or NULL if no match is found. - - Note: One instance where there may be duplicate minimal symbols with - the same name is when the symbol tables for a shared library and the - symbol tables for an executable contain global symbols with the same - names (the dynamic linker deals with the duplication). */ - -struct minimal_symbol * -lookup_minimal_symbol (name, objf) - register const char *name; - struct objfile *objf; -{ - struct objfile *objfile; - struct minimal_symbol *msymbol; - struct minimal_symbol *found_symbol = NULL; - struct minimal_symbol *found_file_symbol = NULL; - struct minimal_symbol *trampoline_symbol = NULL; - - for (objfile = object_files; - objfile != NULL && found_symbol == NULL; - objfile = objfile -> next) - { - if (objf == NULL || objf == objfile) - { - for (msymbol = objfile -> msymbols; - msymbol != NULL && SYMBOL_NAME (msymbol) != NULL && - found_symbol == NULL; - msymbol++) - { - if (SYMBOL_MATCHES_NAME (msymbol, name)) - { - switch (MSYMBOL_TYPE (msymbol)) - { - case mst_file_text: - case mst_file_data: - case mst_file_bss: - /* It is file-local. If we find more than one, just - return the latest one (the user can't expect - useful behavior in that case). */ - found_file_symbol = msymbol; - break; - - case mst_solib_trampoline: - - /* If a trampoline symbol is found, we prefer to - keep looking for the *real* symbol. If the - actual symbol is not found, then we'll use the - trampoline entry. */ - if (trampoline_symbol == NULL) - trampoline_symbol = msymbol; - break; - - case mst_unknown: - default: - found_symbol = msymbol; - break; - } - } - } - } - } - /* External symbols are best. */ - if (found_symbol) - return found_symbol; - - /* File-local symbols are next best. */ - if (found_file_symbol) - return found_file_symbol; - - /* Symbols for shared library trampolines are next best. */ - if (trampoline_symbol) - return trampoline_symbol; - - return NULL; -} - - -/* 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. */ - -struct minimal_symbol * -lookup_minimal_symbol_by_pc (pc) - register CORE_ADDR pc; -{ - 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; - - for (objfile = object_files; - objfile != NULL; - objfile = objfile -> next) - { - /* If this objfile has a minimal symbol table, go search it using - a binary search. Note that a minimal symbol table always consists - of at least two symbols, a "real" symbol and the terminating - "null symbol". If there are no real symbols, then there is no - minimal symbol table at all. */ - - if ((msymbol = objfile -> msymbols) != NULL) - { - lo = 0; - hi = objfile -> minimal_symbol_count - 1; - - /* This code assumes that the minimal symbols are sorted by - ascending address values. If the pc value is greater than or - equal to the first symbol's address, then some symbol in this - minimal symbol table is a suitable candidate for being the - "best" symbol. This includes the last real symbol, for cases - where the pc value is larger than any address in this vector. - - By iterating until the address associated with the current - hi index (the endpoint of the test interval) is less than - or equal to the desired pc value, we accomplish two things: - (1) the case where the pc value is larger than any minimal - symbol address is trivially solved, (2) the address associated - with the hi index is always the one we want when the interation - terminates. In essence, we are iterating the test interval - down until the pc value is pushed out of it from the high end. - - Warning: this code is trickier than it would appear at first. */ - - /* Should also requires that pc is <= end of objfile. FIXME! */ - if (pc >= SYMBOL_VALUE_ADDRESS (&msymbol[lo])) - { - while (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) > pc) - { - /* pc is still strictly less than highest address */ - /* Note "new" will always be >= lo */ - new = (lo + hi) / 2; - if ((SYMBOL_VALUE_ADDRESS (&msymbol[new]) >= pc) || - (lo == new)) - { - hi = new; - } - else - { - lo = new; - } - } - /* The minimal symbol indexed by hi now is the best one in this - objfile's minimal symbol table. See if it is the best one - overall. */ - - /* Skip any absolute symbols. This is apparently what adb - and dbx do, and is needed for the CM-5. There are two - known possible problems: (1) on ELF, apparently end, edata, - etc. are absolute. Not sure ignoring them here is a big - deal, but if we want to use them, the fix would go in - elfread.c. (2) I think shared library entry points on the - NeXT are absolute. If we want special handling for this - it probably should be triggered by a special - mst_abs_or_lib or some such. */ - while (hi >= 0 - && msymbol[hi].type == mst_abs) - --hi; - - if (hi >= 0 - && ((best_symbol == NULL) || - (SYMBOL_VALUE_ADDRESS (best_symbol) < - SYMBOL_VALUE_ADDRESS (&msymbol[hi])))) - { - best_symbol = &msymbol[hi]; - } - } - } - } - return (best_symbol); -} - -/* Prepare to start collecting minimal symbols. Note that presetting - msym_bunch_index to BUNCH_SIZE causes the first call to save a minimal - symbol to allocate the memory for the first bunch. */ - -void -init_minimal_symbol_collection () -{ - msym_count = 0; - msym_bunch = NULL; - msym_bunch_index = BUNCH_SIZE; -} - -void -prim_record_minimal_symbol (name, address, ms_type, objfile) - const char *name; - CORE_ADDR address; - enum minimal_symbol_type ms_type; - struct objfile *objfile; -{ - int section; - - switch (ms_type) - { - case mst_text: - case mst_file_text: - case mst_solib_trampoline: - section = SECT_OFF_TEXT; - break; - case mst_data: - case mst_file_data: - section = SECT_OFF_DATA; - break; - case mst_bss: - case mst_file_bss: - section = SECT_OFF_BSS; - break; - default: - section = -1; - } - - prim_record_minimal_symbol_and_info (name, address, ms_type, - NULL, section, objfile); -} - -void -prim_record_minimal_symbol_and_info (name, address, ms_type, info, section, - objfile) - const char *name; - CORE_ADDR address; - enum minimal_symbol_type ms_type; - char *info; - int section; - struct objfile *objfile; -{ - register struct msym_bunch *new; - register struct minimal_symbol *msymbol; - - if (ms_type == mst_file_text) - { - /* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into - the minimal symbols, because if there is also another symbol - at the same address (e.g. the first function of the file), - lookup_minimal_symbol_by_pc would have no way of getting the - right one. */ - if (name[0] == 'g' - && (strcmp (name, GCC_COMPILED_FLAG_SYMBOL) == 0 - || strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0)) - return; - - { - const char *tempstring = name; - if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd)) - ++tempstring; - if (STREQN (tempstring, "__gnu_compiled", 14)) - return; - } - } - - if (msym_bunch_index == BUNCH_SIZE) - { - new = (struct msym_bunch *) xmalloc (sizeof (struct msym_bunch)); - msym_bunch_index = 0; - new -> next = msym_bunch; - msym_bunch = new; - } - msymbol = &msym_bunch -> contents[msym_bunch_index]; - SYMBOL_NAME (msymbol) = (char *) name; - SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown); - SYMBOL_VALUE_ADDRESS (msymbol) = address; - SYMBOL_SECTION (msymbol) = section; - - MSYMBOL_TYPE (msymbol) = ms_type; - /* FIXME: This info, if it remains, needs its own field. */ - MSYMBOL_INFO (msymbol) = info; /* FIXME! */ - msym_bunch_index++; - msym_count++; -} - -/* Compare two minimal symbols by address and return a signed result based - on unsigned comparisons, so that we sort into unsigned numeric order. */ - -static int -compare_minimal_symbols (fn1p, fn2p) - const PTR fn1p; - const PTR fn2p; -{ - register const struct minimal_symbol *fn1; - register const struct minimal_symbol *fn2; - - fn1 = (const struct minimal_symbol *) fn1p; - fn2 = (const struct minimal_symbol *) fn2p; - - if (SYMBOL_VALUE_ADDRESS (fn1) < SYMBOL_VALUE_ADDRESS (fn2)) - { - return (-1); - } - else if (SYMBOL_VALUE_ADDRESS (fn1) > SYMBOL_VALUE_ADDRESS (fn2)) - { - return (1); - } - else - { - return (0); - } -} - -/* Discard the currently collected minimal symbols, if any. If we wish - to save them for later use, we must have already copied them somewhere - else before calling this function. - - FIXME: We could allocate the minimal symbol bunches on their own - obstack and then simply blow the obstack away when we are done with - it. Is it worth the extra trouble though? */ - -/* ARGSUSED */ -void -discard_minimal_symbols (foo) - int foo; -{ - register struct msym_bunch *next; - - while (msym_bunch != NULL) - { - next = msym_bunch -> next; - free ((PTR)msym_bunch); - msym_bunch = next; - } -} - -/* Compact duplicate entries out of a minimal symbol table by walking - through the table and compacting out entries with duplicate addresses - and matching names. Return the number of entries remaining. - - On entry, the table resides between msymbol[0] and msymbol[mcount]. - On exit, it resides between msymbol[0] and msymbol[result_count]. - - When files contain multiple sources of symbol information, it is - possible for the minimal symbol table to contain many duplicate entries. - As an example, SVR4 systems use ELF formatted object files, which - usually contain at least two different types of symbol tables (a - standard ELF one and a smaller dynamic linking table), as well as - DWARF debugging information for files compiled with -g. - - Without compacting, the minimal symbol table for gdb itself contains - over a 1000 duplicates, about a third of the total table size. Aside - from the potential trap of not noticing that two successive entries - identify the same location, this duplication impacts the time required - to linearly scan the table, which is done in a number of places. So we - just do one linear scan here and toss out the duplicates. - - Note that we are not concerned here about recovering the space that - is potentially freed up, because the strings themselves are allocated - on the symbol_obstack, and will get automatically freed when the symbol - table is freed. The caller can free up the unused minimal symbols at - the end of the compacted region if their allocation strategy allows it. - - Also note we only go up to the next to last entry within the loop - and then copy the last entry explicitly after the loop terminates. - - Since the different sources of information for each symbol may - have different levels of "completeness", we may have duplicates - that have one entry with type "mst_unknown" and the other with a - known type. So if the one we are leaving alone has type mst_unknown, - overwrite its type with the type from the one we are compacting out. */ - -static int -compact_minimal_symbols (msymbol, mcount) - struct minimal_symbol *msymbol; - int mcount; -{ - struct minimal_symbol *copyfrom; - struct minimal_symbol *copyto; - - if (mcount > 0) - { - copyfrom = copyto = msymbol; - while (copyfrom < msymbol + mcount - 1) - { - if (SYMBOL_VALUE_ADDRESS (copyfrom) == - SYMBOL_VALUE_ADDRESS ((copyfrom + 1)) && - (STREQ (SYMBOL_NAME (copyfrom), SYMBOL_NAME ((copyfrom + 1))))) - { - if (MSYMBOL_TYPE((copyfrom + 1)) == mst_unknown) - { - MSYMBOL_TYPE ((copyfrom + 1)) = MSYMBOL_TYPE (copyfrom); - } - copyfrom++; - } - else - { - *copyto++ = *copyfrom++; - } - } - *copyto++ = *copyfrom++; - mcount = copyto - msymbol; - } - return (mcount); -} - -/* Add the minimal symbols in the existing bunches to the objfile's official - minimal symbol table. In most cases there is no minimal symbol table yet - for this objfile, and the existing bunches are used to create one. Once - in a while (for shared libraries for example), we add symbols (e.g. common - symbols) to an existing objfile. - - Because of the way minimal symbols are collected, we generally have no way - of knowing what source language applies to any particular minimal symbol. - Specifically, we have no way of knowing if the minimal symbol comes from a - C++ compilation unit or not. So for the sake of supporting cached - demangled C++ names, we have no choice but to try and demangle each new one - that comes in. If the demangling succeeds, then we assume it is a C++ - symbol and set the symbol's language and demangled name fields - appropriately. Note that in order to avoid unnecessary demanglings, and - allocating obstack space that subsequently can't be freed for the demangled - names, we mark all newly added symbols with language_auto. After - compaction of the minimal symbols, we go back and scan the entire minimal - symbol table looking for these new symbols. For each new symbol we attempt - to demangle it, and if successful, record it as a language_cplus symbol - and cache the demangled form on the symbol obstack. Symbols which don't - demangle are marked as language_unknown symbols, which inhibits future - attempts to demangle them if we later add more minimal symbols. */ - -void -install_minimal_symbols (objfile) - struct objfile *objfile; -{ - register int bindex; - register int mcount; - register struct msym_bunch *bunch; - register struct minimal_symbol *msymbols; - int alloc_count; - register char leading_char; - - if (msym_count > 0) - { - /* Allocate enough space in the obstack, into which we will gather the - bunches of new and existing minimal symbols, sort them, and then - compact out the duplicate entries. Once we have a final table, - we will give back the excess space. */ - - alloc_count = msym_count + objfile->minimal_symbol_count + 1; - obstack_blank (&objfile->symbol_obstack, - alloc_count * sizeof (struct minimal_symbol)); - msymbols = (struct minimal_symbol *) - obstack_base (&objfile->symbol_obstack); - - /* Copy in the existing minimal symbols, if there are any. */ - - if (objfile->minimal_symbol_count) - memcpy ((char *)msymbols, (char *)objfile->msymbols, - objfile->minimal_symbol_count * sizeof (struct minimal_symbol)); - - /* Walk through the list of minimal symbol bunches, adding each symbol - to the new contiguous array of symbols. Note that we start with the - current, possibly partially filled bunch (thus we use the current - msym_bunch_index for the first bunch we copy over), and thereafter - each bunch is full. */ - - mcount = objfile->minimal_symbol_count; - leading_char = bfd_get_symbol_leading_char (objfile->obfd); - - for (bunch = msym_bunch; bunch != NULL; bunch = bunch -> next) - { - for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++) - { - msymbols[mcount] = bunch -> contents[bindex]; - SYMBOL_LANGUAGE (&msymbols[mcount]) = language_auto; - if (SYMBOL_NAME (&msymbols[mcount])[0] == leading_char) - { - SYMBOL_NAME(&msymbols[mcount])++; - } - } - msym_bunch_index = BUNCH_SIZE; - } - - /* Sort the minimal symbols by address. */ - - qsort (msymbols, mcount, sizeof (struct minimal_symbol), - compare_minimal_symbols); - - /* Compact out any duplicates, and free up whatever space we are - no longer using. */ - - mcount = compact_minimal_symbols (msymbols, mcount); - - obstack_blank (&objfile->symbol_obstack, - (mcount + 1 - alloc_count) * sizeof (struct minimal_symbol)); - msymbols = (struct minimal_symbol *) - obstack_finish (&objfile->symbol_obstack); - - /* We also terminate the minimal symbol table with a "null symbol", - which is *not* included in the size of the table. This makes it - easier to find the end of the table when we are handed a pointer - to some symbol in the middle of it. Zero out the fields in the - "null symbol" allocated at the end of the array. Note that the - symbol count does *not* include this null symbol, which is why it - is indexed by mcount and not mcount-1. */ - - SYMBOL_NAME (&msymbols[mcount]) = NULL; - SYMBOL_VALUE_ADDRESS (&msymbols[mcount]) = 0; - MSYMBOL_INFO (&msymbols[mcount]) = NULL; - MSYMBOL_TYPE (&msymbols[mcount]) = mst_unknown; - SYMBOL_INIT_LANGUAGE_SPECIFIC (&msymbols[mcount], language_unknown); - - /* Attach the minimal symbol table to the specified objfile. - The strings themselves are also located in the symbol_obstack - of this objfile. */ - - objfile -> minimal_symbol_count = mcount; - objfile -> msymbols = msymbols; - - /* Now walk through all the minimal symbols, selecting the newly added - ones and attempting to cache their C++ demangled names. */ - - for ( ; mcount-- > 0 ; msymbols++) - { - SYMBOL_INIT_DEMANGLED_NAME (msymbols, &objfile->symbol_obstack); - } - } -} - -/* Check if PC is in a shared library trampoline code stub. - Return minimal symbol for the trampoline entry or NULL if PC is not - in a trampoline code stub. */ - -struct minimal_symbol * -lookup_solib_trampoline_symbol_by_pc (pc) - CORE_ADDR pc; -{ - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc); - - if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) - return msymbol; - return NULL; -} - -/* If PC is in a shared library trampoline code stub, return the - address of the `real' function belonging to the stub. - Return 0 if PC is not in a trampoline code stub or if the real - function is not found in the minimal symbol table. - - We may fail to find the right function if a function with the - same name is defined in more than one shared library, but this - is considered bad programming style. We could return 0 if we find - a duplicate function in case this matters someday. */ - -CORE_ADDR -find_solib_trampoline_target (pc) - CORE_ADDR pc; -{ - struct objfile *objfile; - struct minimal_symbol *msymbol; - struct minimal_symbol *tsymbol = lookup_solib_trampoline_symbol_by_pc (pc); - - if (tsymbol != NULL) - { - ALL_MSYMBOLS (objfile, msymbol) - { - if (MSYMBOL_TYPE (msymbol) == mst_text - && STREQ (SYMBOL_NAME (msymbol), SYMBOL_NAME (tsymbol))) - return SYMBOL_VALUE_ADDRESS (msymbol); - } - } - return 0; -} - diff --git a/gnu/usr.bin/gdb/gdb/mipsread.c b/gnu/usr.bin/gdb/gdb/mipsread.c deleted file mode 100644 index 8c45a94..0000000 --- a/gnu/usr.bin/gdb/gdb/mipsread.c +++ /dev/null @@ -1,457 +0,0 @@ -/* Read a symbol table in MIPS' format (Third-Eye). - Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994 - 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. - -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. */ - -/* Read symbols from an ECOFF file. Most of the work is done in - mdebugread.c. */ - -#include "defs.h" -#include -#include "bfd.h" -#include "symtab.h" -#include "symfile.h" -#include "objfiles.h" -#include "buildsym.h" -#include "stabsread.h" -#include "gdb-stabs.h" - -#include "coff/sym.h" -#include "coff/internal.h" -#include "coff/ecoff.h" -#include "libcoff.h" /* Private BFD COFF information. */ -#include "libecoff.h" /* Private BFD ECOFF information. */ -#include "elf/common.h" -#include "elf/mips.h" - -static void -mipscoff_new_init PARAMS ((struct objfile *)); - -static void -mipscoff_symfile_init PARAMS ((struct objfile *)); - -static void -mipscoff_symfile_read PARAMS ((struct objfile *, struct section_offsets *, - int)); - -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)); - -/* 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). */ - -extern CORE_ADDR sigtramp_address; - -static void -mipscoff_new_init (ignore) - struct objfile *ignore; -{ - sigtramp_address = 0; - stabsread_new_init (); - buildsym_new_init (); -} - -/* Initialize to read a symbol file (nothing to do). */ - -static void -mipscoff_symfile_init (objfile) - struct objfile *objfile; -{ -} - -/* Read a symbol file from a file. */ - -static void -mipscoff_symfile_read (objfile, section_offsets, mainline) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; -{ - bfd *abfd = objfile->obfd; - struct cleanup * back_to; - - init_minimal_symbol_collection (); - back_to = make_cleanup (discard_minimal_symbols, 0); - - /* Now that the executable file is positioned at symbol table, - process it and define symbols accordingly. */ - - if (!((*ecoff_backend (abfd)->debug_swap.read_debug_info) - (abfd, (asection *) NULL, &ecoff_data (abfd)->debug_info))) - error ("Error reading symbol table: %s", bfd_errmsg (bfd_get_error ())); - - mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap, - &ecoff_data (abfd)->debug_info, section_offsets); - - /* Add the dynamic symbols if we are reading the main symbol table. */ - - if (mainline) - read_alphacoff_dynamic_symtab (section_offsets, objfile); - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); - - do_cleanups (back_to); -} - -/* Perform any local cleanups required when we are done with a - particular objfile. */ - -static void -mipscoff_symfile_finish (objfile) - struct objfile *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 - format is used, and the representation only changes because longs are - 64 bit on the alpha. In addition, the handling of text/data section - indices for symbols is different from the ELF ABI. - As the BFD linker currently does not support dynamic linking on the alpha, - there seems to be no reason to pollute BFD with another mixture of object - file formats for now. */ - -/* Format of an alpha external ELF symbol. */ - -typedef struct { - unsigned char st_name[4]; /* Symbol name, index in string tbl */ - unsigned char st_pad[4]; /* Pad to long word boundary */ - unsigned char st_value[8]; /* Value of the symbol */ - unsigned char st_size[4]; /* Associated symbol size */ - unsigned char st_info[1]; /* Type and binding attributes */ - unsigned char st_other[1]; /* No defined meaning, 0 */ - unsigned char st_shndx[2]; /* Associated section index */ -} Elfalpha_External_Sym; - -/* Format of an alpha external ELF dynamic info structure. */ - -typedef struct { - unsigned char d_tag[4]; /* Tag */ - unsigned char d_pad[4]; /* Pad to long word boundary */ - union { - unsigned char d_ptr[8]; /* Pointer value */ - unsigned char d_val[4]; /* Integer value */ - } d_un; -} Elfalpha_External_Dyn; - -/* Struct to obtain the section pointers for alpha dynamic symbol info. */ - -struct alphacoff_dynsecinfo { - asection *sym_sect; /* Section pointer for .dynsym section */ - asection *str_sect; /* Section pointer for .dynstr section */ - asection *dyninfo_sect; /* Section pointer for .dynamic section */ - asection *got_sect; /* Section pointer for .got section */ -}; - -static void -alphacoff_locate_sections PARAMS ((bfd *, asection *, void *)); - -/* We are called once per section from read_alphacoff_dynamic_symtab. - We need to examine each section we are passed, check to see - if it is something we are interested in processing, and - if so, stash away some access information for the section. */ - -static void -alphacoff_locate_sections (ignore_abfd, sectp, sip) - bfd *ignore_abfd; - asection *sectp; - PTR sip; -{ - register struct alphacoff_dynsecinfo *si; - - si = (struct alphacoff_dynsecinfo *) sip; - - if (STREQ (sectp->name, ".dynsym")) - { - si->sym_sect = sectp; - } - else if (STREQ (sectp->name, ".dynstr")) - { - si->str_sect = sectp; - } - else if (STREQ (sectp->name, ".dynamic")) - { - si->dyninfo_sect = sectp; - } - else if (STREQ (sectp->name, ".got")) - { - si->got_sect = sectp; - } -} - -/* Scan an alpha dynamic symbol table for symbols of interest and - add them to the minimal symbol table. */ - -static void -read_alphacoff_dynamic_symtab (section_offsets, objfile) - struct section_offsets *section_offsets; - struct objfile *objfile; -{ - bfd *abfd = objfile->obfd; - struct alphacoff_dynsecinfo si; - char *sym_secptr; - char *str_secptr; - char *dyninfo_secptr; - char *got_secptr; - bfd_size_type sym_secsize; - bfd_size_type str_secsize; - bfd_size_type dyninfo_secsize; - bfd_size_type got_secsize; - int sym_count; - int i; - int stripped; - Elfalpha_External_Sym *x_symp; - char *dyninfo_p; - char *dyninfo_end; - int got_entry_size = 8; - int dt_mips_local_gotno = -1; - int dt_mips_gotsym = -1; - - - /* We currently only know how to handle alpha dynamic symbols. */ - if (bfd_get_arch (abfd) != bfd_arch_alpha) - return; - - /* Locate the dynamic symbols sections and read them in. */ - memset ((char *) &si, 0, sizeof (si)); - bfd_map_over_sections (abfd, alphacoff_locate_sections, (PTR) &si); - if (si.sym_sect == NULL - || si.str_sect == NULL - || si.dyninfo_sect == NULL - || si.got_sect == NULL) - return; - - sym_secsize = bfd_get_section_size_before_reloc (si.sym_sect); - str_secsize = bfd_get_section_size_before_reloc (si.str_sect); - dyninfo_secsize = bfd_get_section_size_before_reloc (si.dyninfo_sect); - got_secsize = bfd_get_section_size_before_reloc (si.got_sect); - sym_secptr = alloca (sym_secsize); - str_secptr = alloca (str_secsize); - dyninfo_secptr = alloca (dyninfo_secsize); - got_secptr = alloca (got_secsize); - - if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr, - (file_ptr)0, sym_secsize)) - return; - if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr, - (file_ptr)0, str_secsize)) - return; - if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr, - (file_ptr)0, dyninfo_secsize)) - return; - if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr, - (file_ptr)0, got_secsize)) - return; - - /* Find the number of local GOT entries and the index for the - the first dynamic symbol in the GOT. */ - for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize; - dyninfo_p < dyninfo_end; - dyninfo_p += sizeof (Elfalpha_External_Dyn)) - { - Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *)dyninfo_p; - long dyn_tag; - - dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag); - if (dyn_tag == DT_NULL) - break; - else if (dyn_tag == DT_MIPS_LOCAL_GOTNO) - { - dt_mips_local_gotno = bfd_h_get_32 (abfd, - (bfd_byte *) x_dynp->d_un.d_val); - } - else if (dyn_tag == DT_MIPS_GOTSYM) - { - dt_mips_gotsym = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val); - } - } - if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0) - return; - - /* Scan all dynamic symbols and enter them into the minimal symbol table - if appropriate. */ - sym_count = sym_secsize / sizeof (Elfalpha_External_Sym); - stripped = (bfd_get_symcount (abfd) == 0); - - /* Skip first symbol, which is a null dummy. */ - for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1; - i < sym_count; - i++, x_symp++) - { - unsigned long strx; - char *name; - bfd_vma sym_value; - unsigned char sym_info; - unsigned int sym_shndx; - int isglobal; - enum minimal_symbol_type ms_type; - - strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name); - if (strx >= str_secsize) - continue; - name = str_secptr + strx; - if (*name == '\0' || *name == '.') - continue; - - sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value); - sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info); - sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx); - isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL); - - if (sym_shndx == SHN_UNDEF) - { - /* Handle undefined functions which are defined in a shared - library. */ - if (ELF_ST_TYPE (sym_info) != STT_FUNC - || ELF_ST_BIND (sym_info) != STB_GLOBAL) - continue; - - ms_type = mst_solib_trampoline; - - /* If sym_value is nonzero, it points to the shared library - trampoline entry, which is what we are looking for. - - If sym_value is zero, then we have to get the GOT entry - for the symbol. - If the GOT entry is nonzero, it represents the quickstart - address of the function and we use that as the symbol value. - - If the GOT entry is zero, the function address has to be resolved - by the runtime loader before the executable is started. - We are unable to find any meaningful address for these - functions in the executable file, so we skip them. */ - if (sym_value == 0) - { - int got_entry_offset = - (i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size; - - if (got_entry_offset < 0 || got_entry_offset >= got_secsize) - continue; - sym_value = - bfd_h_get_64 (abfd, - (bfd_byte *) (got_secptr + got_entry_offset)); - if (sym_value == 0) - continue; - } - } - else - { - /* Symbols defined in the executable itself. We only care about - them if this is a stripped executable, otherwise they have - been retrieved from the normal symbol table already. */ - if (!stripped) - continue; - - if (sym_shndx == SHN_MIPS_TEXT) - { - if (isglobal) - ms_type = mst_text; - else - ms_type = mst_file_text; - sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT); - } - else if (sym_shndx == SHN_MIPS_DATA) - { - if (isglobal) - ms_type = mst_data; - else - ms_type = mst_file_data; - sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA); - } - else if (sym_shndx == SHN_MIPS_ACOMMON) - { - if (isglobal) - ms_type = mst_bss; - else - ms_type = mst_file_bss; - sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS); - } - else if (sym_shndx == SHN_ABS) - { - ms_type = mst_abs; - } - else - { - continue; - } - } - - prim_record_minimal_symbol (obsavestring (name, - strlen (name), - &objfile -> symbol_obstack), - sym_value, - ms_type, - objfile); - } -} - -/* Initialization */ - -static struct sym_fns ecoff_sym_fns = -{ - bfd_target_ecoff_flavour, - mipscoff_new_init, /* sym_new_init: init anything gbl to entire symtab */ - 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 */ - NULL /* next: pointer to next struct sym_fns */ -}; - -void -_initialize_mipsread () -{ - add_symtab_fns (&ecoff_sym_fns); -} diff --git a/gnu/usr.bin/gdb/gdb/nlmread.c b/gnu/usr.bin/gdb/gdb/nlmread.c deleted file mode 100644 index b2ebbe0..0000000 --- a/gnu/usr.bin/gdb/gdb/nlmread.c +++ /dev/null @@ -1,308 +0,0 @@ -/* Read NLM (NetWare Loadable Module) format executable files for GDB. - Copyright 1993, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include -#include "bfd.h" -#include "symtab.h" -#include "symfile.h" -#include "objfiles.h" -#include "gdb-stabs.h" -#include "buildsym.h" -#include "stabsread.h" - -static void -nlm_new_init PARAMS ((struct objfile *)); - -static void -nlm_symfile_init PARAMS ((struct objfile *)); - -static void -nlm_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int)); - -static void -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). - - We reinitialize buildsym, since gdb will be able to read stabs from an NLM - file at some point in the near future. */ - -static void -nlm_new_init (ignore) - struct objfile *ignore; -{ - stabsread_new_init (); - buildsym_new_init (); -} - - -/* NLM specific initialization routine for reading symbols. - - It is passed a pointer to a struct sym_fns which contains, among other - things, the BFD for the file whose symbols are being read, and a slot for - a pointer to "private data" which we can fill with goodies. - - For now at least, we have nothing in particular to do, so this function is - just a stub. */ - -static void -nlm_symfile_init (ignore) - struct objfile *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 - - nlm_symtab_read -- read the symbol table of an NLM file - -SYNOPSIS - - void nlm_symtab_read (bfd *abfd, CORE_ADDR addr, - struct objfile *objfile) - -DESCRIPTION - - Given an open bfd, a base address to relocate symbols to, and a - flag that specifies whether or not this bfd is for an executable - or not (may be shared library for example), add all the global - function and data symbols to the minimal symbol table. -*/ - -static void -nlm_symtab_read (abfd, addr, objfile) - bfd *abfd; - CORE_ADDR addr; - struct objfile *objfile; -{ - long storage_needed; - asymbol *sym; - asymbol **symbol_table; - long number_of_symbols; - long i; - struct cleanup *back_to; - CORE_ADDR symaddr; - enum minimal_symbol_type ms_type; - - storage_needed = bfd_get_symtab_upper_bound (abfd); - if (storage_needed < 0) - error ("Can't read symbols from %s: %s", bfd_get_filename (abfd), - bfd_errmsg (bfd_get_error ())); - if (storage_needed > 0) - { - symbol_table = (asymbol **) xmalloc (storage_needed); - back_to = make_cleanup (free, symbol_table); - number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); - if (number_of_symbols < 0) - error ("Can't read symbols from %s: %s", bfd_get_filename (abfd), - bfd_errmsg (bfd_get_error ())); - - for (i = 0; i < number_of_symbols; i++) - { - sym = symbol_table[i]; - if (/*sym -> flags & BSF_GLOBAL*/ 1) - { - /* Bfd symbols are section relative. */ - symaddr = sym -> value + sym -> section -> vma; - /* Relocate all non-absolute symbols by base address. */ - if (sym -> section != &bfd_abs_section) - symaddr += addr; - - /* For non-absolute symbols, use the type of the section - they are relative to, to intuit text/data. BFD provides - no way of figuring this out for absolute symbols. */ - if (sym -> section -> flags & SEC_CODE) - ms_type = mst_text; - else if (sym -> section -> flags & SEC_DATA) - ms_type = mst_data; - else - ms_type = mst_unknown; - - record_minimal_symbol ((char *) sym -> name, symaddr, ms_type, - objfile); - } - } - do_cleanups (back_to); - } -} - - -/* Scan and build partial symbols for a symbol file. - We have been initialized by a call to nlm_symfile_init, which - currently does nothing. - - SECTION_OFFSETS is a set of offsets to apply to relocate the symbols - in each section. We simplify it down to a single offset for all - symbols. FIXME. - - MAINLINE is true if we are reading the main symbol - table (as opposed to a shared lib or dynamically loaded file). - - This function only does the minimum work necessary for letting the - user "name" things symbolically; it does not read the entire symtab. - Instead, it reads the external and static symbols and puts them in partial - symbol tables. When more extensive information is requested of a - file, the corresponding partial symbol table is mutated into a full - fledged symbol table by going back and reading the symbols - for real. - - Note that NLM files have two sets of information that is potentially - useful for building gdb's minimal symbol table. The first is a list - of the publically exported symbols, and is currently used to build - bfd's canonical symbol table. The second is an optional native debugging - format which contains additional symbols (and possibly duplicates of - the publically exported symbols). The optional native debugging format - is not currently used. */ - -static void -nlm_symfile_read (objfile, section_offsets, mainline) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; -{ - bfd *abfd = objfile -> obfd; - struct cleanup *back_to; - CORE_ADDR offset; - struct symbol *mainsym; - - init_minimal_symbol_collection (); - back_to = make_cleanup (discard_minimal_symbols, 0); - - /* FIXME, should take a section_offsets param, not just an offset. */ - - offset = ANOFFSET (section_offsets, 0); - - /* Process the NLM export records, which become the bfd's canonical symbol - table. */ - - nlm_symtab_read (abfd, offset, objfile); - - stabsect_build_psymtabs (objfile, section_offsets, mainline, ".stab", - ".stabstr", ".text"); - - mainsym = lookup_symbol ("main", NULL, VAR_NAMESPACE, NULL, NULL); - - if (mainsym - && SYMBOL_CLASS(mainsym) == LOC_BLOCK) - { - objfile->ei.main_func_lowpc = BLOCK_START (SYMBOL_BLOCK_VALUE (mainsym)); - objfile->ei.main_func_highpc = BLOCK_END (SYMBOL_BLOCK_VALUE (mainsym)); - } - - /* FIXME: We could locate and read the optional native debugging format - here and add the symbols to the minimal symbol table. */ - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); - - do_cleanups (back_to); -} - - -/* 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. */ - -static void -nlm_symfile_finish (objfile) - struct objfile *objfile; -{ - if (objfile -> sym_private != NULL) - { - mfree (objfile -> md, objfile -> sym_private); - } -} - -/* 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 = -{ - bfd_target_nlm_flavour, - nlm_new_init, /* sym_new_init: init anything gbl to entire symtab */ - 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 */ - NULL /* next: pointer to next struct sym_fns */ -}; - -void -_initialize_nlmread () -{ - add_symtab_fns (&nlm_sym_fns); -} diff --git a/gnu/usr.bin/gdb/gdb/nm.h b/gnu/usr.bin/gdb/gdb/nm.h index ec85bd8..6affe1a 100644 --- a/gnu/usr.bin/gdb/gdb/nm.h +++ b/gnu/usr.bin/gdb/gdb/nm.h @@ -1,5 +1,5 @@ /* Native-dependent definitions for Intel 386 running BSD Unix, for GDB. - Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc. + Copyright 1986, 1987, 1989, 1992, 1996 Free Software Foundation, Inc. This file is part of GDB. @@ -15,10 +15,12 @@ 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef NM_FREEBSD_H -#define NM_FREEBSD_H +#ifndef NM_FBSD_H +#define NM_FBSD_H + +#define ATTACH_DETACH /* Be shared lib aware */ #include "solib.h" @@ -29,10 +31,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #define KERNEL_U_ADDR USRSTACK -/* #undef FLOAT_INFO */ /* No float info yet */ -#define FLOAT_INFO extern void i386_float_info (); \ - i386_float_info () - #define REGISTER_U_ADDR(addr, blockend, regno) \ (addr) = i386_register_u_addr ((blockend),(regno)); @@ -40,61 +38,81 @@ extern int i386_register_u_addr PARAMS ((int, int)); #define PTRACE_ARG3_TYPE char* -#define ATTACH_DETACH -#define KERNEL_DEBUG /* make structure definitions match up with those expected in solib.c */ - -#define link_object sod -#define lo_name sod_name -#define lo_library sod_library -#define lo_unused sod_reserved -#define lo_major sod_major -#define lo_minor sod_minor -#define lo_next sod_next - -#define link_map so_map -#define lm_addr som_addr -#define lm_name som_path -#define lm_next som_next -#define lm_lop som_sod -#define lm_lob som_sodbase -#define lm_rwt som_write -#define lm_ld som_dynamic -#define lm_lpd som_spd - -#define link_dynamic_2 section_dispatch_table -#define ld_loaded sdt_loaded -#define ld_need sdt_sods -#define ld_rules sdt_filler1 -#define ld_got sdt_got -#define ld_plt sdt_plt -#define ld_rel sdt_rel -#define ld_hash sdt_hash -#define ld_stab sdt_nzlist -#define ld_stab_hash sdt_filler2 -#define ld_buckets sdt_buckets -#define ld_symbols sdt_strings -#define ld_symb_size sdt_str_sz -#define ld_text sdt_text_sz -#define ld_plt_sz sdt_plt_sz - -#define rtc_symb rt_symbol -#define rtc_sp rt_sp -#define rtc_next rt_next - -#define ld_debug so_debug -#define ldd_version dd_version -#define ldd_in_debugger dd_in_debugger -#define ldd_sym_loaded dd_sym_loaded -#define ldd_bp_addr dd_bpt_addr -#define ldd_bp_inst dd_bpt_shadow -#define ldd_cp dd_cc - -#define link_dynamic _dynamic -#define ld_version d_version -#define ldd d_debug -#define ld_un d_un -#define ld_2 d_sdt - -#endif /* NM_FREEBSD_H */ +#define link_object sod +#define lo_name sod_name +#define lo_library sod_library +#define lo_unused sod_reserved +#define lo_major sod_major +#define lo_minor sod_minor +#define lo_next sod_next + +#define link_map so_map +#define lm_addr som_addr +#define lm_name som_path +#define lm_next som_next +#define lm_lop som_sod +#define lm_lob som_sodbase +#define lm_rwt som_write +#define lm_ld som_dynamic +#define lm_lpd som_spd + +#define link_dynamic_2 section_dispatch_table +#define ld_loaded sdt_loaded +#define ld_need sdt_sods +#define ld_rules sdt_filler1 +#define ld_got sdt_got +#define ld_plt sdt_plt +#define ld_rel sdt_rel +#define ld_hash sdt_hash +#define ld_stab sdt_nzlist +#define ld_stab_hash sdt_filler2 +#define ld_buckets sdt_buckets +#define ld_symbols sdt_strings +#define ld_symb_size sdt_str_sz +#define ld_text sdt_text_sz +#define ld_plt_sz sdt_plt_sz + +#define rtc_symb rt_symbol +#define rtc_sp rt_sp +#define rtc_next rt_next + +#define ld_debug so_debug +#define ldd_version dd_version +#define ldd_in_debugger dd_in_debugger +#define ldd_sym_loaded dd_sym_loaded +#define ldd_bp_addr dd_bpt_addr +#define ldd_bp_inst dd_bpt_shadow +#define ldd_cp dd_cc + +#define link_dynamic _dynamic +#define ld_version d_version +#define ldd d_debug +#define ld_un d_un +#define ld_2 d_sdt + +/* 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)); + +#define ADDITIONAL_OPTIONS \ + {"kernel", no_argument, &kernel_debugging, 1}, \ + {"k", no_argument, &kernel_debugging, 1}, \ + {"wcore", no_argument, &kernel_writablecore, 1}, \ + {"w", no_argument, &kernel_writablecore, 1}, + +#define ADDITIONAL_OPTION_HELP \ + "\ + --kernel Enable kernel debugging.\n\ + --wcore Make core file writable (only works for /dev/mem).\n\ + This option only works while debugging a kernel !!\n\ +" + +extern int kernel_debugging; +extern int kernel_writablecore; + +#define DEFAULT_PROMPT kernel_debugging?"(kgdb) ":"(gdb) " + +#endif /* NM_FBSD_H */ diff --git a/gnu/usr.bin/gdb/gdb/objfiles.c b/gnu/usr.bin/gdb/gdb/objfiles.c deleted file mode 100644 index 8ec08a2..0000000 --- a/gnu/usr.bin/gdb/gdb/objfiles.c +++ /dev/null @@ -1,868 +0,0 @@ -/* GDB routines for manipulating objfiles. - Copyright 1992 Free Software Foundation, Inc. - Contributed by Cygnus Support, using pieces from other GDB modules. - -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. */ - -/* This file contains support routines for creating, manipulating, and - destroying objfile structures. */ - -#include "defs.h" -#include "bfd.h" /* Binary File Description */ -#include "symtab.h" -#include "symfile.h" -#include "objfiles.h" -#include "gdb-stabs.h" -#include "target.h" - -#include -#include -#include -#include - -/* Prototypes for local functions */ - -#if !defined(NO_MMALLOC) && defined(HAVE_MMAP) - -static int -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)); - -#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */ - -/* Message to be printed before the error message, when an error occurs. */ - -extern char *error_pre_print; - -/* Externally visible variables that are owned by this module. - See declarations in objfile.h for more info. */ - -struct objfile *object_files; /* Linked list of all objfiles */ -struct objfile *current_objfile; /* For symbol file being read in */ -struct objfile *symfile_objfile; /* Main symbol table loaded from */ - -int mapped_symbol_files; /* Try to use mapped symbol files */ - -/* Locate all mappable sections of a BFD file. - objfile_p_char is a char * to get it through - bfd_map_over_sections; we cast it back to its proper type. */ - -static void -add_to_objfile_sections (abfd, asect, objfile_p_char) - bfd *abfd; - sec_ptr asect; - PTR objfile_p_char; -{ - struct objfile *objfile = (struct objfile *) objfile_p_char; - struct obj_section section; - flagword aflag; - - aflag = bfd_get_section_flags (abfd, asect); - if (!(aflag & SEC_ALLOC)) - return; - if (0 == bfd_section_size (abfd, asect)) - return; - section.offset = 0; - section.objfile = objfile; - section.the_bfd_section = asect; - section.addr = bfd_section_vma (abfd, asect); - section.endaddr = section.addr + bfd_section_size (abfd, asect); - obstack_grow (&objfile->psymbol_obstack, §ion, sizeof(section)); - objfile->sections_end = (struct obj_section *) (((unsigned long) objfile->sections_end) + 1); -} - -/* Builds a section table for OBJFILE. - Returns 0 if OK, 1 on error (in which case bfd_error contains the - error). */ - -int -build_objfile_section_table (objfile) - struct objfile *objfile; -{ - /* objfile->sections can be already set when reading a mapped symbol - file. I believe that we do need to rebuild the section table in - this case (we rebuild other things derived from the bfd), but we - can't free the old one (it's in the psymbol_obstack). So we just - waste some memory. */ - - objfile->sections_end = 0; - bfd_map_over_sections (objfile->obfd, add_to_objfile_sections, (char *)objfile); - objfile->sections = (struct obj_section *) - obstack_finish (&objfile->psymbol_obstack); - objfile->sections_end = objfile->sections + (unsigned long) objfile->sections_end; - return(0); -} - -/* 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. */ - -struct objfile * -allocate_objfile (abfd, mapped) - bfd *abfd; - int mapped; -{ - struct objfile *objfile = NULL; - - mapped |= mapped_symbol_files; - -#if !defined(NO_MMALLOC) && defined(HAVE_MMAP) - { - - /* If we can support mapped symbol files, try to open/reopen the - mapped file that corresponds to the file from which we wish to - read symbols. If the objfile is to be mapped, we must malloc - the structure itself using the mmap version, and arrange that - all memory allocation for the objfile uses the mmap routines. - If we are reusing an existing mapped file, from which we get - our objfile pointer, we have to make sure that we update the - pointers to the alloc/free functions in the obstack, in case - these functions have moved within the current gdb. */ - - int fd; - - fd = open_mapped_file (bfd_get_filename (abfd), bfd_get_mtime (abfd), - mapped); - if (fd >= 0) - { - CORE_ADDR mapto; - PTR md; - - if (((mapto = map_to_address ()) == 0) || - ((md = mmalloc_attach (fd, (PTR) mapto)) == NULL)) - { - close (fd); - } - else if ((objfile = (struct objfile *) mmalloc_getkey (md, 0)) != NULL) - { - /* Update memory corruption handler function addresses. */ - init_malloc (md); - objfile -> md = md; - objfile -> mmfd = fd; - /* Update pointers to functions to *our* copies */ - obstack_chunkfun (&objfile -> psymbol_obstack, xmmalloc); - obstack_freefun (&objfile -> psymbol_obstack, mfree); - obstack_chunkfun (&objfile -> symbol_obstack, xmmalloc); - obstack_freefun (&objfile -> symbol_obstack, mfree); - obstack_chunkfun (&objfile -> type_obstack, xmmalloc); - obstack_freefun (&objfile -> type_obstack, mfree); - /* If already in objfile list, unlink it. */ - unlink_objfile (objfile); - /* Forget things specific to a particular gdb, may have changed. */ - objfile -> sf = NULL; - } - else - { - - /* Set up to detect internal memory corruption. MUST be - done before the first malloc. See comments in - init_malloc() and mmcheck(). */ - - init_malloc (md); - - objfile = (struct objfile *) - xmmalloc (md, sizeof (struct objfile)); - memset (objfile, 0, sizeof (struct objfile)); - objfile -> md = md; - objfile -> mmfd = fd; - objfile -> flags |= OBJF_MAPPED; - mmalloc_setkey (objfile -> md, 0, objfile); - obstack_specify_allocation_with_arg (&objfile -> psymbol_obstack, - 0, 0, xmmalloc, mfree, - objfile -> md); - obstack_specify_allocation_with_arg (&objfile -> symbol_obstack, - 0, 0, xmmalloc, mfree, - objfile -> md); - obstack_specify_allocation_with_arg (&objfile -> type_obstack, - 0, 0, xmmalloc, mfree, - objfile -> md); - } - } - - if (mapped && (objfile == NULL)) - { - warning ("symbol table for '%s' will not be mapped", - bfd_get_filename (abfd)); - } - } -#else /* defined(NO_MMALLOC) || !defined(HAVE_MMAP) */ - - if (mapped) - { - warning ("this version of gdb does not support mapped symbol tables."); - - /* Turn off the global flag so we don't try to do mapped symbol tables - any more, which shuts up gdb unless the user specifically gives the - "mapped" keyword again. */ - - mapped_symbol_files = 0; - } - -#endif /* !defined(NO_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 - back to an unmapped objfile. */ - - if (objfile == NULL) - { - objfile = (struct objfile *) xmalloc (sizeof (struct objfile)); - memset (objfile, 0, sizeof (struct objfile)); - objfile -> md = NULL; - obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0, xmalloc, - free); - obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0, xmalloc, - free); - obstack_specify_allocation (&objfile -> type_obstack, 0, 0, xmalloc, - free); - } - - /* Update the per-objfile information that comes from the bfd, ensuring - that any data that is reference is saved in the per-objfile data - region. */ - - objfile -> obfd = abfd; - if (objfile -> name != NULL) - { - mfree (objfile -> md, objfile -> name); - } - objfile -> name = mstrsave (objfile -> md, bfd_get_filename (abfd)); - objfile -> mtime = bfd_get_mtime (abfd); - - /* 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 ())); - } - - /* Push this file onto the head of the linked list of other such files. */ - - objfile -> next = object_files; - object_files = objfile; - - return (objfile); -} - -/* Unlink OBJFILE from the list of known objfiles, if it is found in the - list. - - It is not a bug, or error, to call this function if OBJFILE is not known - to be in the current list. This is done in the case of mapped objfiles, - for example, just to ensure that the mapped objfile doesn't appear twice - in the list. Since the list is threaded, linking in a mapped objfile - twice would create a circular list. - - If OBJFILE turns out to be in the list, we zap it's NEXT pointer after - unlinking it, just to ensure that we have completely severed any linkages - between the OBJFILE and the list. */ - -void -unlink_objfile (objfile) - struct objfile *objfile; -{ - struct objfile** objpp; - - for (objpp = &object_files; *objpp != NULL; objpp = &((*objpp) -> next)) - { - if (*objpp == objfile) - { - *objpp = (*objpp) -> next; - objfile -> next = NULL; - break; - } - } -} - - -/* Destroy an objfile and all the symtabs and psymtabs under it. Note - that as much as possible is allocated on the symbol_obstack and - psymbol_obstack, so that the memory can be efficiently freed. - - Things which we do NOT free because they are not in malloc'd memory - or not in memory specific to the objfile include: - - objfile -> sf - - FIXME: If the objfile is using reusable symbol information (via mmalloc), - then we need to take into account the fact that more than one process - may be using the symbol information at the same time (when mmalloc is - extended to support cooperative locking). When more than one process - is using the mapped symbol info, we need to be more careful about when - we free objects in the reusable area. */ - -void -free_objfile (objfile) - struct objfile *objfile; -{ - /* First do any symbol file specific actions required when we are - finished with a particular symbol file. Note that if the objfile - is using reusable symbol information (via mmalloc) then each of - these routines is responsible for doing the correct thing, either - freeing things which are valid only during this particular gdb - execution, or leaving them to be reused during the next one. */ - - if (objfile -> sf != NULL) - { - (*objfile -> sf -> sym_finish) (objfile); - } - - /* We always close the bfd. */ - - if (objfile -> obfd != NULL) - { - char *name = bfd_get_filename (objfile->obfd); - bfd_close (objfile -> obfd); - free (name); - } - - /* Remove it from the chain of all objfiles. */ - - unlink_objfile (objfile); - - /* Before the symbol table code was redone to make it easier to - selectively load and remove information particular to a specific - linkage unit, gdb used to do these things whenever the monolithic - symbol table was blown away. How much still needs to be done - is unknown, but we play it safe for now and keep each action until - it is shown to be no longer needed. */ - -#if defined (CLEAR_SOLIB) - CLEAR_SOLIB (); - /* CLEAR_SOLIB closes the bfd's for any shared libraries. But - the to_sections for a core file might refer to those bfd's. So - detach any core file. */ - { - struct target_ops *t = find_core_target (); - if (t != NULL) - (t->to_detach) (NULL, 0); - } -#endif - /* I *think* all our callers call clear_symtab_users. If so, no need - to call this here. */ - clear_pc_function_cache (); - - /* The last thing we do is free the objfile struct itself for the - non-reusable case, or detach from the mapped file for the reusable - 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 (objfile -> flags & OBJF_MAPPED) - { - /* Remember the fd so we can close it. We can't close it before - doing the detach, and after the detach the objfile is gone. */ - int mmfd; - - mmfd = objfile -> mmfd; - mmalloc_detach (objfile -> md); - objfile = NULL; - close (mmfd); - } - -#endif /* !defined(NO_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. */ - - if (objfile != NULL) - { - if (objfile -> name != NULL) - { - mfree (objfile -> md, objfile -> name); - } - if (objfile->global_psymbols.list) - mfree (objfile->md, objfile->global_psymbols.list); - if (objfile->static_psymbols.list) - mfree (objfile->md, objfile->static_psymbols.list); - /* Free the obstacks for non-reusable objfiles */ - obstack_free (&objfile -> psymbol_obstack, 0); - obstack_free (&objfile -> symbol_obstack, 0); - obstack_free (&objfile -> type_obstack, 0); - mfree (objfile -> md, objfile); - objfile = NULL; - } -} - - -/* Free all the object files at once and clean up their users. */ - -void -free_all_objfiles () -{ - struct objfile *objfile, *temp; - - ALL_OBJFILES_SAFE (objfile, temp) - { - free_objfile (objfile); - } - clear_symtab_users (); -} - -/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS - entries in new_offsets. */ -void -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)); - - { - int i; - int something_changed = 0; - for (i = 0; i < objfile->num_sections; ++i) - { - ANOFFSET (delta, i) = - ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i); - if (ANOFFSET (delta, i) != 0) - something_changed = 1; - } - if (!something_changed) - return; - } - - /* OK, get all the symtabs. */ - { - struct symtab *s; - - ALL_OBJFILE_SYMTABS (objfile, s) - { - struct linetable *l; - struct blockvector *bv; - int i; - - /* First the line table. */ - l = LINETABLE (s); - if (l) - { - for (i = 0; i < l->nitems; ++i) - l->item[i].pc += ANOFFSET (delta, s->block_line_section); - } - - /* Don't relocate a shared blockvector more than once. */ - if (!s->primary) - continue; - - bv = BLOCKVECTOR (s); - for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i) - { - struct block *b; - int j; - - b = BLOCKVECTOR_BLOCK (bv, i); - BLOCK_START (b) += ANOFFSET (delta, s->block_line_section); - BLOCK_END (b) += ANOFFSET (delta, s->block_line_section); - - for (j = 0; j < BLOCK_NSYMS (b); ++j) - { - struct symbol *sym = BLOCK_SYM (b, j); - /* The RS6000 code from which this was taken skipped - any symbols in STRUCT_NAMESPACE or UNDEF_NAMESPACE. - 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_SECTION (sym) >= 0) - { - SYMBOL_VALUE_ADDRESS (sym) += - ANOFFSET (delta, SYMBOL_SECTION (sym)); - } -#ifdef MIPS_EFI_SYMBOL_NAME - /* Relocate Extra Function Info for ecoff. */ - - else - 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)); -#endif - } - } - } - } - - { - struct partial_symtab *p; - - ALL_OBJFILE_PSYMTABS (objfile, p) - { - /* FIXME: specific to symbol readers which use gdb-stabs.h. - We can only get away with it since objfile_relocate is only - used on XCOFF, which lacks psymtabs, and for gdb-stabs.h - targets. */ - p->textlow += ANOFFSET (delta, SECT_OFF_TEXT); - p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT); - } - } - - { - struct partial_symbol *psym; - - for (psym = objfile->global_psymbols.list; - psym < objfile->global_psymbols.next; - psym++) - if (SYMBOL_SECTION (psym) >= 0) - 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)); - } - - { - struct minimal_symbol *msym; - ALL_OBJFILE_MSYMBOLS (objfile, msym) - if (SYMBOL_SECTION (msym) >= 0) - SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym)); - } - - { - int i; - for (i = 0; i < objfile->num_sections; ++i) - ANOFFSET (objfile->section_offsets, i) = ANOFFSET (new_offsets, i); - } - - { - struct obj_section *s; - bfd *abfd; - - abfd = symfile_objfile->obfd; - - for (s = symfile_objfile->sections; - s < symfile_objfile->sections_end; ++s) - { - flagword flags; - - flags = bfd_get_section_flags (abfd, s->the_bfd_section); - - if (flags & SEC_CODE) - { - 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->endaddr += ANOFFSET (delta, SECT_OFF_DATA); - } - else if (flags & SEC_ALLOC) - { - s->addr += ANOFFSET (delta, SECT_OFF_BSS); - s->endaddr += ANOFFSET (delta, SECT_OFF_BSS); - } - } - } - - if (objfile->ei.entry_point != ~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_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_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_highpc += ANOFFSET (delta, SECT_OFF_TEXT); - } -} - -/* Many places in gdb want to test just to see if we have any partial - symbols available. This function returns zero if none are currently - available, nonzero otherwise. */ - -int -have_partial_symbols () -{ - struct objfile *ofp; - - ALL_OBJFILES (ofp) - { - if (ofp -> psymtabs != NULL) - { - return 1; - } - } - return 0; -} - -/* Many places in gdb want to test just to see if we have any full - symbols available. This function returns zero if none are currently - available, nonzero otherwise. */ - -int -have_full_symbols () -{ - struct objfile *ofp; - - ALL_OBJFILES (ofp) - { - if (ofp -> symtabs != NULL) - { - return 1; - } - } - return 0; -} - -/* 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. */ - -int -have_minimal_symbols () -{ - struct objfile *ofp; - - ALL_OBJFILES (ofp) - { - if (ofp -> msymbols != NULL) - { - return 1; - } - } - return 0; -} - -#if !defined(NO_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 - with the name SYMSFILENAME and verify it is more recent than the base - file by checking it's timestamp against MTIME. - - If SYMSFILENAME does not exist (or can't be stat'd), simply returns -1. - - If SYMSFILENAME does exist, but is out of date, we check to see if the - user has specified creation of a mapped file. If so, we don't issue - any warning message because we will be creating a new mapped file anyway, - overwriting the old one. If not, then we issue a warning message so that - the user will know why we aren't using this existing mapped symbol file. - In either case, we return -1. - - If SYMSFILENAME does exist and is not out of date, but can't be opened for - some reason, then prints an appropriate system error message and returns -1. - - Otherwise, returns the open file descriptor. */ - -static int -open_existing_mapped_file (symsfilename, mtime, mapped) - char *symsfilename; - long mtime; - int mapped; -{ - int fd = -1; - struct stat sbuf; - - if (stat (symsfilename, &sbuf) == 0) - { - if (sbuf.st_mtime < mtime) - { - if (!mapped) - { - warning ("mapped symbol file `%s' is out of date, ignored it", - symsfilename); - } - } - else if ((fd = open (symsfilename, O_RDWR)) < 0) - { - if (error_pre_print) - { - printf_unfiltered (error_pre_print); - } - print_sys_errmsg (symsfilename, errno); - } - } - return (fd); -} - -/* Look for a mapped symbol file that corresponds to FILENAME and is more - recent than MTIME. If MAPPED is nonzero, the user has asked that gdb - use a mapped symbol file for this file, so create a new one if one does - not currently exist. - - If found, then return an open file descriptor for the file, otherwise - return -1. - - This routine is responsible for implementing the policy that generates - the name of the mapped symbol file from the name of a file containing - symbols that gdb would like to read. Currently this policy is to append - ".syms" to the name of the file. - - This routine is also responsible for implementing the policy that - determines where the mapped symbol file is found (the search path). - This policy is that when reading an existing mapped file, a file of - the correct name in the current directory takes precedence over a - file of the correct name in the same directory as the symbol file. - When creating a new mapped file, it is always created in the current - directory. This helps to minimize the chances of a user unknowingly - creating big mapped files in places like /bin and /usr/local/bin, and - allows a local copy to override a manually installed global copy (in - /bin for example). */ - -static int -open_mapped_file (filename, mtime, mapped) - char *filename; - long mtime; - int mapped; -{ - int fd; - char *symsfilename; - - /* First try to open an existing file in the current directory, and - then try the directory where the symbol file is located. */ - - symsfilename = concat ("./", basename (filename), ".syms", (char *) NULL); - if ((fd = open_existing_mapped_file (symsfilename, mtime, mapped)) < 0) - { - free (symsfilename); - symsfilename = concat (filename, ".syms", (char *) NULL); - fd = open_existing_mapped_file (symsfilename, mtime, mapped); - } - - /* If we don't have an open file by now, then either the file does not - already exist, or the base file has changed since it was created. In - either case, if the user has specified use of a mapped file, then - create a new mapped file, truncating any existing one. If we can't - create one, print a system error message saying why we can't. - - By default the file is rw for everyone, with the user's umask taking - care of turning off the permissions the user wants off. */ - - if ((fd < 0) && mapped) - { - free (symsfilename); - symsfilename = concat ("./", basename (filename), ".syms", - (char *) NULL); - if ((fd = open (symsfilename, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0) - { - if (error_pre_print) - { - printf_unfiltered (error_pre_print); - } - print_sys_errmsg (symsfilename, errno); - } - } - - free (symsfilename); - 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 () -{ - -#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 - - return (0); - -#endif - -} - -#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */ - -/* Returns a section whose range includes PC or NULL if none found. */ - -struct obj_section * -find_pc_section(pc) - CORE_ADDR pc; -{ - 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) - return(s); - - return(NULL); -} - -/* 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. */ - -int -in_plt_section(pc, name) - CORE_ADDR pc; - char *name; -{ - struct obj_section *s; - int retval = 0; - - s = find_pc_section(pc); - - retval = (s != NULL - && s->the_bfd_section->name != NULL - && STREQ (s->the_bfd_section->name, ".plt")); - return(retval); -} diff --git a/gnu/usr.bin/gdb/gdb/objfiles.h b/gnu/usr.bin/gdb/gdb/objfiles.h deleted file mode 100644 index b1aa8c9..0000000 --- a/gnu/usr.bin/gdb/gdb/objfiles.h +++ /dev/null @@ -1,451 +0,0 @@ -/* Definitions for symbol file management in GDB. - Copyright (C) 1992, 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. */ - -#if !defined (OBJFILES_H) -#define OBJFILES_H - -/* This structure maintains information on a per-objfile basis about the - "entry point" of the objfile, and the scope within which the entry point - exists. It is possible that gdb will see more than one objfile that is - executable, each with its own entry point. - - For example, for dynamically linked executables in SVR4, the dynamic linker - code is contained within the shared C library, which is actually executable - and is run by the kernel first when an exec is done of a user executable - that is dynamically linked. The dynamic linker within the shared C library - then maps in the various program segments in the user executable and jumps - to the user executable's recorded entry point, as if the call had been made - directly by the kernel. - - The traditional gdb method of using this info is to use the recorded entry - point to set the variables entry_file_lowpc and entry_file_highpc from - the debugging information, where these values are the starting address - (inclusive) and ending address (exclusive) of the instruction space in the - executable which correspond to the "startup file", I.E. crt0.o in most - cases. This file is assumed to be a startup file and frames with pc's - inside it are treated as nonexistent. Setting these variables is necessary - so that backtraces do not fly off the bottom of the stack. - - Gdb also supports an alternate method to avoid running off the bottom - of the stack. - - There are two frames that are "special", the frame for the function - containing the process entry point, since it has no predecessor frame, - and the frame for the function containing the user code entry point - (the main() function), since all the predecessor frames are for the - process startup code. Since we have no guarantee that the linked - in startup modules have any debugging information that gdb can use, - we need to avoid following frame pointers back into frames that might - have been built in the startup code, as we might get hopelessly - confused. However, we almost always have debugging information - available for main(). - - These variables are used to save the range of PC values which are valid - within the main() function and within the function containing the process - entry point. If we always consider the frame for main() as the outermost - frame when debugging user code, and the frame for the process entry - point function as the outermost frame when debugging startup code, then - all we have to do is have FRAME_CHAIN_VALID return false whenever a - frame's current PC is within the range specified by these variables. - In essence, we set "ceilings" in the frame chain beyond which we will - not proceed when following the frame chain back up the stack. - - A nice side effect is that we can still debug startup code without - running off the end of the frame chain, assuming that we have usable - debugging information in the startup modules, and if we choose to not - use the block at main, or can't find it for some reason, everything - still works as before. And if we have no startup code debugging - information but we do have usable information for main(), backtraces - from user code don't go wandering off into the startup code. - - To use this method, define your FRAME_CHAIN_VALID macro like: - - #define FRAME_CHAIN_VALID(chain, thisframe) \ - (chain != 0 \ - && !(inside_main_func ((thisframe)->pc)) \ - && !(inside_entry_func ((thisframe)->pc))) - - and add initializations of the four scope controlling variables inside - the object file / debugging information processing modules. */ - -struct entry_info -{ - - /* The value we should use for this objects entry point. - The illegal/unknown value needs to be something other than 0, ~0 - for instance, which is much less likely than 0. */ - - CORE_ADDR entry_point; - -#define INVALID_ENTRY_POINT (~0) /* ~0 will not be in any file, we hope. */ - - /* Start (inclusive) and end (exclusive) of function containing the - entry point. */ - - CORE_ADDR entry_func_lowpc; - CORE_ADDR entry_func_highpc; - - /* Start (inclusive) and end (exclusive) of object file containing the - entry point. */ - - CORE_ADDR entry_file_lowpc; - CORE_ADDR entry_file_highpc; - - /* Start (inclusive) and end (exclusive) of the user code main() function. */ - - CORE_ADDR main_func_lowpc; - CORE_ADDR main_func_highpc; - -/* Use these values when any of the above ranges is invalid. */ - -/* We use these values because it guarantees that there is no number that is - both >= LOWPC && < HIGHPC. It is also highly unlikely that 3 is a valid - module or function start address (as opposed to 0). */ - -#define INVALID_ENTRY_LOWPC (3) -#define INVALID_ENTRY_HIGHPC (1) - -}; - -/* Sections in an objfile. - - It is strange that we have both this notion of "sections" - and the one used by section_offsets. Section as used - here, (currently at least) means a BFD section, and the sections - are set up from the BFD sections in allocate_objfile. - - The sections in section_offsets have their meaning determined by - the symbol format, and they are set up by the sym_offsets function - for that symbol file format. - - I'm not sure this could or should be changed, however. */ - -struct obj_section { - CORE_ADDR addr; /* lowest address in section */ - CORE_ADDR endaddr; /* 1+highest address in section */ - - /* This field is being used for nefarious purposes by syms_from_objfile. - It is said to be redundant with section_offsets; it's not really being - used that way, however, it's some sort of hack I don't understand - and am not going to try to eliminate (yet, anyway). FIXME. - - It was documented as "offset between (end)addr and actual memory - addresses", but that's not true; addr & endaddr are actual memory - addresses. */ - CORE_ADDR offset; - - sec_ptr the_bfd_section; /* BFD section pointer */ - - /* Objfile this section is part of. */ - struct objfile *objfile; -}; - -/* Master structure for keeping track of each file from which - gdb reads symbols. There are several ways these get allocated: 1. - The main symbol file, symfile_objfile, set by the symbol-file command, - 2. Additional symbol files added by the add-symbol-file command, - 3. Shared library objfiles, added by ADD_SOLIB, 4. symbol files - for modules that were loaded when GDB attached to a remote system - (see remote-vx.c). */ - -struct objfile -{ - - /* All struct objfile's are chained together by their next pointers. - The global variable "object_files" points to the first link in this - chain. - - FIXME: There is a problem here if the objfile is reusable, and if - multiple users are to be supported. The problem is that the objfile - list is linked through a member of the objfile struct itself, which - is only valid for one gdb process. The list implementation needs to - be changed to something like: - - struct list {struct list *next; struct objfile *objfile}; - - where the list structure is completely maintained separately within - each gdb process. */ - - struct objfile *next; - - /* The object file's name. Malloc'd; free it if you free this struct. */ - - char *name; - - /* Some flag bits for this objfile. */ - - unsigned short flags; - - /* Each objfile points to a linked list of symtabs derived from this file, - one symtab structure for each compilation unit (source file). Each link - in the symtab list contains a backpointer to this objfile. */ - - struct symtab *symtabs; - - /* Each objfile points to a linked list of partial symtabs derived from - this file, one partial symtab structure for each compilation unit - (source file). */ - - struct partial_symtab *psymtabs; - - /* List of freed partial symtabs, available for re-use */ - - struct partial_symtab *free_psymtabs; - - /* The object file's BFD. Can be null, in which case bfd_open (name) and - put the result here. */ - - bfd *obfd; - - /* The modification timestamp of the object file, as of the last time - we read its symbols. */ - - long mtime; - - /* Obstacks to hold objects that should be freed when we load a new symbol - table from this object file. */ - - struct obstack psymbol_obstack; /* Partial symbols */ - struct obstack symbol_obstack; /* Full symbols */ - struct obstack type_obstack; /* Types */ - - /* Vectors of all partial symbols read in from file. The actual data - is stored in the psymbol_obstack. */ - - struct psymbol_allocation_list global_psymbols; - struct psymbol_allocation_list static_psymbols; - - /* Each file contains a pointer to an array of minimal symbols for all - global symbols that are defined within the file. The array is terminated - by a "null symbol", one that has a NULL pointer for the name and a zero - value for the address. This makes it easy to walk through the array - when passed a pointer to somewhere in the middle of it. There is also - a count of the number of symbols, which does include the terminating - null symbol. The array itself, as well as all the data that it points - to, should be allocated on the symbol_obstack for this file. */ - - struct minimal_symbol *msymbols; - int minimal_symbol_count; - - /* For object file formats which don't specify fundamental types, gdb - can create such types. For now, it maintains a vector of pointers - to these internally created fundamental types on a per objfile basis, - however it really should ultimately keep them on a per-compilation-unit - basis, to account for linkage-units that consist of a number of - compilation units that may have different fundamental types, such as - linking C modules with ADA modules, or linking C modules that are - compiled with 32-bit ints with C modules that are compiled with 64-bit - ints (not inherently evil with a smarter linker). */ - - struct type **fundamental_types; - - /* The mmalloc() malloc-descriptor for this objfile if we are using - the memory mapped malloc() package to manage storage for this objfile's - data. NULL if we are not. */ - - PTR md; - - /* The file descriptor that was used to obtain the mmalloc descriptor - for this objfile. If we call mmalloc_detach with the malloc descriptor - we should then close this file descriptor. */ - - int mmfd; - - /* Structure which keeps track of functions that manipulate objfile's - of the same type as this objfile. I.E. the function to read partial - symbols for example. Note that this structure is in statically - allocated memory, and is shared by all objfiles that use the - object module reader of this type. */ - - struct sym_fns *sf; - - /* The per-objfile information about the entry point, the scope (file/func) - containing the entry point, and the scope of the user's main() func. */ - - struct entry_info ei; - - /* Information about stabs. Will be filled in with a dbx_symfile_info - struct by those readers that need it. */ - - PTR 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 - typically a pointer to malloc'd memory. The symbol reader's finish - function is responsible for freeing the memory thusly allocated. */ - - PTR sym_private; - - /* Hook for target-architecture-specific information. This must - point to memory allocated on one of the obstacks in this objfile, - so that it gets freed automatically when reading a new object - file. */ - - PTR obj_private; - - /* Set of relocation offsets to apply to each section. - Currently on the psymbol_obstack (which makes no sense, but I'm - not sure it's harming anything). - - These offsets indicate that all symbols (including partial and - minimal symbols) which have been read have been relocated by this - much. Symbols which are yet to be read need to be relocated by - it. */ - - struct section_offsets *section_offsets; - int num_sections; - - /* set of section begin and end addresses used to map pc addresses - into sections. Currently on the psymbol_obstack (which makes no - sense, but I'm not sure it's harming anything). */ - - struct obj_section - *sections, - *sections_end; - - /* two auxiliary fields, used to hold the fp of separate symbol files */ - FILE *auxf1, *auxf2; -}; - -/* Defines for the objfile flag word. */ - -/* Gdb can arrange to allocate storage for all objects related to a - particular objfile in a designated section of its address space, - managed at a low level by mmap() and using a special version of - malloc that handles malloc/free/realloc on top of the mmap() interface. - This allows the "internal gdb state" for a particular objfile to be - dumped to a gdb state file and subsequently reloaded at a later time. */ - -#define OBJF_MAPPED (1 << 0) /* Objfile data is mmap'd */ - -/* When using mapped/remapped predigested gdb symbol information, we need - a flag that indicates that we have previously done an initial symbol - table read from this particular objfile. We can't just look for the - absence of any of the three symbol tables (msymbols, psymtab, symtab) - because if the file has no symbols for example, none of these will - exist. */ - -#define OBJF_SYMS (1 << 1) /* Have tried to read symbols */ - -/* The object file that the main symbol table was loaded from (e.g. the - argument to the "symbol-file" or "file" command). */ - -extern struct objfile *symfile_objfile; - -/* When we need to allocate a new type, we need to know which type_obstack - to allocate the type on, since there is one for each objfile. The places - where types are allocated are deeply buried in function call hierarchies - which know nothing about objfiles, so rather than trying to pass a - particular objfile down to them, we just do an end run around them and - set current_objfile to be whatever objfile we expect to be using at the - time types are being allocated. For instance, when we start reading - symbols for a particular objfile, we set current_objfile to point to that - objfile, and when we are done, we set it back to NULL, to ensure that we - never put a type someplace other than where we are expecting to put it. - FIXME: Maybe we should review the entire type handling system and - see if there is a better way to avoid this problem. */ - -extern struct objfile *current_objfile; - -/* All known objfiles are kept in a linked list. This points to the - root of this list. */ - -extern struct objfile *object_files; - -/* Declarations for functions defined in objfiles.c */ - -extern struct objfile * -allocate_objfile PARAMS ((bfd *, int)); - -extern int -build_objfile_section_table PARAMS ((struct objfile *)); - -extern void -unlink_objfile PARAMS ((struct objfile *)); - -extern void -free_objfile PARAMS ((struct objfile *)); - -extern void -free_all_objfiles PARAMS ((void)); - -extern void -objfile_relocate PARAMS ((struct objfile *, struct section_offsets *)); - -extern int -have_partial_symbols PARAMS ((void)); - -extern int -have_full_symbols 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. */ - -extern int -have_minimal_symbols PARAMS ((void)); - -extern struct obj_section * -find_pc_section PARAMS((CORE_ADDR pc)); - -/* Traverse all object files. ALL_OBJFILES_SAFE works even if you delete - the objfile during the traversal. */ - -#define ALL_OBJFILES(obj) \ - for ((obj) = object_files; (obj) != NULL; (obj) = (obj)->next) - -#define ALL_OBJFILES_SAFE(obj,nxt) \ - for ((obj) = object_files; \ - (obj) != NULL? ((nxt)=(obj)->next,1) :0; \ - (obj) = (nxt)) - -/* Traverse all symtabs in one objfile. */ - -#define ALL_OBJFILE_SYMTABS(objfile, s) \ - for ((s) = (objfile) -> symtabs; (s) != NULL; (s) = (s) -> next) - -/* Traverse all psymtabs in one objfile. */ - -#define ALL_OBJFILE_PSYMTABS(objfile, p) \ - for ((p) = (objfile) -> psymtabs; (p) != NULL; (p) = (p) -> next) - -/* Traverse all minimal symbols in one objfile. */ - -#define ALL_OBJFILE_MSYMBOLS(objfile, m) \ - for ((m) = (objfile) -> msymbols; SYMBOL_NAME(m) != NULL; (m)++) - -/* Traverse all symtabs in all objfiles. */ - -#define ALL_SYMTABS(objfile, s) \ - ALL_OBJFILES (objfile) \ - ALL_OBJFILE_SYMTABS (objfile, s) - -/* Traverse all psymtabs in all objfiles. */ - -#define ALL_PSYMTABS(objfile, p) \ - ALL_OBJFILES (objfile) \ - ALL_OBJFILE_PSYMTABS (objfile, p) - -/* Traverse all minimal symbols in all objfiles. */ - -#define ALL_MSYMBOLS(objfile, m) \ - ALL_OBJFILES (objfile) \ - if ((objfile)->msymbols) \ - ALL_OBJFILE_MSYMBOLS (objfile, m) - -#endif /* !defined (OBJFILES_H) */ diff --git a/gnu/usr.bin/gdb/gdb/obstack.h b/gnu/usr.bin/gdb/gdb/obstack.h deleted file mode 100644 index 59ceace5..0000000 --- a/gnu/usr.bin/gdb/gdb/obstack.h +++ /dev/null @@ -1,513 +0,0 @@ -/* obstack.h - object stack macros - Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU Library 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 Library General Public License for more details. - -You should have received a copy of the GNU Library General Public License -along with this program; if not, write to the Free Software -Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Summary: - -All the apparent functions defined here are macros. The idea -is that you would use these pre-tested macros to solve a -very specific set of problems, and they would run fast. -Caution: no side-effects in arguments please!! They may be -evaluated MANY times!! - -These macros operate a stack of objects. Each object starts life -small, and may grow to maturity. (Consider building a word syllable -by syllable.) An object can move while it is growing. Once it has -been "finished" it never changes address again. So the "top of the -stack" is typically an immature growing object, while the rest of the -stack is of mature, fixed size and fixed address objects. - -These routines grab large chunks of memory, using a function you -supply, called `obstack_chunk_alloc'. On occasion, they free chunks, -by calling `obstack_chunk_free'. You must define them and declare -them before using any obstack macros. - -Each independent stack is represented by a `struct obstack'. -Each of the obstack macros expects a pointer to such a structure -as the first argument. - -One motivation for this package is the problem of growing char strings -in symbol tables. Unless you are "fascist pig with a read-only mind" ---Gosper's immortal quote from HAKMEM item 154, out of context--you -would not like to put any arbitrary upper limit on the length of your -symbols. - -In practice this often means you will build many short symbols and a -few long symbols. At the time you are reading a symbol you don't know -how long it is. One traditional method is to read a symbol into a -buffer, realloc()ating the buffer every time you try to read a symbol -that is longer than the buffer. This is beaut, but you still will -want to copy the symbol from the buffer to a more permanent -symbol-table entry say about half the time. - -With obstacks, you can work differently. Use one obstack for all symbol -names. As you read a symbol, grow the name in the obstack gradually. -When the name is complete, finalize it. Then, if the symbol exists already, -free the newly read name. - -The way we do this is to take a large chunk, allocating memory from -low addresses. When you want to build a symbol in the chunk you just -add chars above the current "high water mark" in the chunk. When you -have finished adding chars, because you got to the end of the symbol, -you know how long the chars are, and you can create a new object. -Mostly the chars will not burst over the highest address of the chunk, -because you would typically expect a chunk to be (say) 100 times as -long as an average object. - -In case that isn't clear, when we have enough chars to make up -the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) -so we just point to it where it lies. No moving of chars is -needed and this is the second win: potentially long strings need -never be explicitly shuffled. Once an object is formed, it does not -change its address during its lifetime. - -When the chars burst over a chunk boundary, we allocate a larger -chunk, and then copy the partly formed object from the end of the old -chunk to the beginning of the new larger chunk. We then carry on -accreting characters to the end of the object as we normally would. - -A special macro is provided to add a single char at a time to a -growing object. This allows the use of register variables, which -break the ordinary 'growth' macro. - -Summary: - We allocate large chunks. - We carve out one object at a time from the current chunk. - Once carved, an object never moves. - We are free to append data of any size to the currently - growing object. - Exactly one object is growing in an obstack at any one time. - You can run one obstack per control block. - You may have as many control blocks as you dare. - Because of the way we do it, you can `unwind' an obstack - back to a previous state. (You may remove objects much - as you would with a stack.) -*/ - - -/* Don't do the contents of this file more than once. */ - -#ifndef __OBSTACK_H__ -#define __OBSTACK_H__ - -/* We use subtraction of (char *)0 instead of casting to int - because on word-addressable machines a simple cast to int - may ignore the byte-within-word field of the pointer. */ - -#ifndef __PTR_TO_INT -#define __PTR_TO_INT(P) ((P) - (char *)0) -#endif - -#ifndef __INT_TO_PTR -#define __INT_TO_PTR(P) ((P) + (char *)0) -#endif - -/* We need the type of the resulting object. In ANSI C it is ptrdiff_t - but in traditional C it is usually long. If we are in ANSI C and - don't already have ptrdiff_t get it. */ - -#if defined (__STDC__) && ! defined (offsetof) -#if defined (__GNUC__) && defined (IN_GCC) -/* On Next machine, the system's stddef.h screws up if included - after we have defined just ptrdiff_t, so include all of stddef.h. - Otherwise, define just ptrdiff_t, which is all we need. */ -#ifndef __NeXT__ -#define __need_ptrdiff_t -#endif -#endif - -#include -#endif - -#ifdef __STDC__ -#define PTR_INT_TYPE ptrdiff_t -#else -#define PTR_INT_TYPE long -#endif - -struct _obstack_chunk /* Lives at front of each chunk. */ -{ - char *limit; /* 1 past end of this chunk */ - struct _obstack_chunk *prev; /* address of prior chunk or NULL */ - char contents[4]; /* objects begin here */ -}; - -struct obstack /* control current object in current chunk */ -{ - long chunk_size; /* preferred size to allocate chunks in */ - struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */ - char *object_base; /* address of object we are building */ - char *next_free; /* where to add next char to current object */ - char *chunk_limit; /* address of char after current chunk */ - PTR_INT_TYPE temp; /* Temporary for some macros. */ - int alignment_mask; /* Mask of alignment for each object. */ - struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ - void (*freefun) (); /* User's function to free a chunk. */ - char *extra_arg; /* first arg for chunk alloc/dealloc funcs */ - unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ - unsigned maybe_empty_object:1;/* There is a possibility that the current - chunk contains a zero-length object. This - prevents freeing the chunk if we allocate - a bigger chunk to replace it. */ - unsigned alloc_failed:1; /* chunk alloc func returned 0 */ -}; - -/* Declare the external functions we use; they are in obstack.c. */ - -#ifdef __STDC__ -extern void _obstack_newchunk (struct obstack *, int); -extern void _obstack_free (struct obstack *, void *); -extern int _obstack_begin (struct obstack *, int, int, - void *(*) (), void (*) ()); -extern int _obstack_begin_1 (struct obstack *, int, int, - void *(*) (), void (*) (), void *); -#else -extern void _obstack_newchunk (); -extern void _obstack_free (); -extern int _obstack_begin (); -extern int _obstack_begin_1 (); -#endif - -#ifdef __STDC__ - -/* Do the function-declarations after the structs - but before defining the macros. */ - -void obstack_init (struct obstack *obstack); - -void * obstack_alloc (struct obstack *obstack, int size); - -void * obstack_copy (struct obstack *obstack, void *address, int size); -void * obstack_copy0 (struct obstack *obstack, void *address, int size); - -void obstack_free (struct obstack *obstack, void *block); - -void obstack_blank (struct obstack *obstack, int size); - -void obstack_grow (struct obstack *obstack, void *data, int size); -void obstack_grow0 (struct obstack *obstack, void *data, int size); - -void obstack_1grow (struct obstack *obstack, int data_char); -void obstack_ptr_grow (struct obstack *obstack, void *data); -void obstack_int_grow (struct obstack *obstack, int data); - -void * obstack_finish (struct obstack *obstack); - -int obstack_object_size (struct obstack *obstack); - -int obstack_room (struct obstack *obstack); -void obstack_1grow_fast (struct obstack *obstack, int data_char); -void obstack_ptr_grow_fast (struct obstack *obstack, void *data); -void obstack_int_grow_fast (struct obstack *obstack, int data); -void obstack_blank_fast (struct obstack *obstack, int size); - -void * obstack_base (struct obstack *obstack); -void * obstack_next_free (struct obstack *obstack); -int obstack_alignment_mask (struct obstack *obstack); -int obstack_chunk_size (struct obstack *obstack); - -#endif /* __STDC__ */ - -/* Non-ANSI C cannot really support alternative functions for these macros, - so we do not declare them. */ - -/* Pointer to beginning of object being allocated or to be allocated next. - Note that this might not be the final address of the object - because a new chunk might be needed to hold the final size. */ - -#define obstack_base(h) ((h)->alloc_failed ? 0 : (h)->object_base) - -/* Size for allocating ordinary chunks. */ - -#define obstack_chunk_size(h) ((h)->chunk_size) - -/* Pointer to next byte not yet allocated in current chunk. */ - -#define obstack_next_free(h) ((h)->alloc_failed ? 0 : (h)->next_free) - -/* Mask specifying low bits that should be clear in address of an object. */ - -#define obstack_alignment_mask(h) ((h)->alignment_mask) - -#define obstack_init(h) \ - _obstack_begin ((h), 0, 0, \ - (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) - -#define obstack_begin(h, size) \ - _obstack_begin ((h), (size), 0, \ - (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) - -#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ - _obstack_begin ((h), (size), (alignment), \ - (void *(*) ()) (chunkfun), (void (*) ()) (freefun)) - -#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ - _obstack_begin_1 ((h), (size), (alignment), \ - (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg)) - -#define obstack_chunkfun(h, newchunkfun) \ - ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun)) - -#define obstack_freefun(h, newfreefun) \ - ((h) -> freefun = (void (*)()) (newfreefun)) - -#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar) - -#define obstack_blank_fast(h,n) ((h)->next_free += (n)) - -#if defined (__GNUC__) && defined (__STDC__) -#if __GNUC__ < 2 -#define __extension__ -#endif - -/* For GNU C, if not -traditional, - we can define these macros to compute all args only once - without using a global variable. - Also, we can avoid using the `temp' slot, to make faster code. */ - -#define obstack_object_size(OBSTACK) \ - __extension__ \ - ({ struct obstack *__o = (OBSTACK); \ - __o->alloc_failed ? 0 : \ - (unsigned) (__o->next_free - __o->object_base); }) - -#define obstack_room(OBSTACK) \ - __extension__ \ - ({ struct obstack *__o = (OBSTACK); \ - (unsigned) (__o->chunk_limit - __o->next_free); }) - -#define obstack_grow(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len > __o->chunk_limit) \ - _obstack_newchunk (__o, __len); \ - if (!__o->alloc_failed) \ - { \ - bcopy (where, __o->next_free, __len); \ - __o->next_free += __len; \ - } \ - (void) 0; }) - -#define obstack_grow0(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len + 1 > __o->chunk_limit) \ - _obstack_newchunk (__o, __len + 1); \ - if (!__o->alloc_failed) \ - { \ - bcopy (where, __o->next_free, __len); \ - __o->next_free += __len; \ - *(__o->next_free)++ = 0; \ - } \ - (void) 0; }) - -#define obstack_1grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + 1 > __o->chunk_limit) \ - _obstack_newchunk (__o, 1); \ - if (!__o->alloc_failed) \ - *(__o->next_free)++ = (datum); \ - (void) 0; }) - -/* These assume that the obstack alignment is good enough for pointers or ints, - and that the data added so far to the current object - shares that much alignment. */ - -#define obstack_ptr_grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ - _obstack_newchunk (__o, sizeof (void *)); \ - if (!__o->alloc_failed) \ - *((void **)__o->next_free)++ = ((void *)datum); \ - (void) 0; }) - -#define obstack_int_grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (int) > __o->chunk_limit) \ - _obstack_newchunk (__o, sizeof (int)); \ - if (!__o->alloc_failed) \ - *((int *)__o->next_free)++ = ((int)datum); \ - (void) 0; }) - -#define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr) -#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) - -#define obstack_blank(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->chunk_limit - __o->next_free < __len) \ - _obstack_newchunk (__o, __len); \ - if (!__o->alloc_failed) \ - __o->next_free += __len; \ - (void) 0; }) - -#define obstack_alloc(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_blank (__h, (length)); \ - obstack_finish (__h); }) - -#define obstack_copy(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_grow (__h, (where), (length)); \ - obstack_finish (__h); }) - -#define obstack_copy0(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_grow0 (__h, (where), (length)); \ - obstack_finish (__h); }) - -/* The local variable is named __o1 to avoid a name conflict - when obstack_blank is called. */ -#define obstack_finish(OBSTACK) \ -__extension__ \ -({ struct obstack *__o1 = (OBSTACK); \ - void *value; \ - if (__o1->alloc_failed) \ - value = 0; \ - else \ - { \ - value = (void *) __o1->object_base; \ - if (__o1->next_free == value) \ - __o1->maybe_empty_object = 1; \ - __o1->next_free \ - = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ - & ~ (__o1->alignment_mask)); \ - if (__o1->next_free - (char *)__o1->chunk \ - > __o1->chunk_limit - (char *)__o1->chunk) \ - __o1->next_free = __o1->chunk_limit; \ - __o1->object_base = __o1->next_free; \ - } \ - value; }) - -#define obstack_free(OBSTACK, OBJ) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - void *__obj = (OBJ); \ - if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ - __o->next_free = __o->object_base = __obj; \ - else (obstack_free) (__o, __obj); }) - -#else /* not __GNUC__ or not __STDC__ */ - -#define obstack_object_size(h) \ - (unsigned) ((h)->alloc_failed ? 0 : (h)->next_free - (h)->object_base) - -#define obstack_room(h) \ - (unsigned) ((h)->chunk_limit - (h)->next_free) - -/* Note that the call to _obstack_newchunk is enclosed in (..., 0) - so that we can avoid having void expressions - in the arms of the conditional expression. - Casting the third operand to void was tried before, - but some compilers won't accept it. */ - -#define obstack_grow(h,where,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (bcopy (where, (h)->next_free, (h)->temp), \ - (h)->next_free += (h)->temp))) - -#define obstack_grow0(h,where,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (bcopy (where, (h)->next_free, (h)->temp), \ - (h)->next_free += (h)->temp, \ - *((h)->next_free)++ = 0))) - -#define obstack_1grow(h,datum) \ -( (((h)->next_free + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), 1), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (*((h)->next_free)++ = (datum)))) - -#define obstack_ptr_grow(h,datum) \ -( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (*((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum)))) - -#define obstack_int_grow(h,datum) \ -( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - (*((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum)))) - -#define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr) -#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) - -#define obstack_blank(h,length) \ -( (h)->temp = (length), \ - (((h)->chunk_limit - (h)->next_free < (h)->temp) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ - ((h)->alloc_failed ? 0 : \ - ((h)->next_free += (h)->temp))) - -#define obstack_alloc(h,length) \ - (obstack_blank ((h), (length)), obstack_finish ((h))) - -#define obstack_copy(h,where,length) \ - (obstack_grow ((h), (where), (length)), obstack_finish ((h))) - -#define obstack_copy0(h,where,length) \ - (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) - -#define obstack_finish(h) \ -( (h)->alloc_failed ? 0 : \ - (((h)->next_free == (h)->object_base \ - ? (((h)->maybe_empty_object = 1), 0) \ - : 0), \ - (h)->temp = __PTR_TO_INT ((h)->object_base), \ - (h)->next_free \ - = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ - & ~ ((h)->alignment_mask)), \ - (((h)->next_free - (char *)(h)->chunk \ - > (h)->chunk_limit - (char *)(h)->chunk) \ - ? ((h)->next_free = (h)->chunk_limit) : 0), \ - (h)->object_base = (h)->next_free, \ - __INT_TO_PTR ((h)->temp))) - -#ifdef __STDC__ -#define obstack_free(h,obj) \ -( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ - (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ - ? (int) ((h)->next_free = (h)->object_base \ - = (h)->temp + (char *) (h)->chunk) \ - : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) -#else -#define obstack_free(h,obj) \ -( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ - (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ - ? (int) ((h)->next_free = (h)->object_base \ - = (h)->temp + (char *) (h)->chunk) \ - : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0))) -#endif - -#endif /* not __GNUC__ or not __STDC__ */ - -#endif /* not __OBSTACK_H__ */ diff --git a/gnu/usr.bin/gdb/gdb/parse.c b/gnu/usr.bin/gdb/gdb/parse.c deleted file mode 100644 index 5fb0683..0000000 --- a/gnu/usr.bin/gdb/gdb/parse.c +++ /dev/null @@ -1,890 +0,0 @@ -/* Parse expressions for GDB. - Copyright (C) 1986, 1989, 1990, 1991, 1994 Free Software Foundation, Inc. - Modified from expread.y by the Department of Computer Science at the - State University of New York at Buffalo, 1991. - -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. */ - -/* Parse an 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. */ - -#include "defs.h" -#include -#include "symtab.h" -#include "gdbtypes.h" -#include "frame.h" -#include "expression.h" -#include "value.h" -#include "command.h" -#include "language.h" -#include "parser-defs.h" - -/* Global variables declared in parser-defs.h (and commented there). */ -struct expression *expout; -int expout_size; -int expout_ptr; -struct block *expression_context_block; -struct block *innermost_block; -int arglist_len; -union type_stack_elt *type_stack; -int type_stack_depth, type_stack_size; -char *lexptr; -char *namecopy; -int paren_depth; -int comma_terminates; - -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)); - -/* Data structure for saving values of arglist_len for function calls whose - arguments contain other function calls. */ - -struct funcall - { - struct funcall *next; - int arglist_len; - }; - -static struct funcall *funcall_chain; - -/* Assign machine-independent names to certain registers - (unless overridden by the REGISTER_NAMES table) */ - -#ifdef NO_STD_REGS -unsigned num_std_regs = 0; -struct std_regs std_regs[1]; -#else -struct std_regs std_regs[] = { - -#ifdef PC_REGNUM - { "pc", PC_REGNUM }, -#endif -#ifdef FP_REGNUM - { "fp", FP_REGNUM }, -#endif -#ifdef SP_REGNUM - { "sp", SP_REGNUM }, -#endif -#ifdef PS_REGNUM - { "ps", PS_REGNUM }, -#endif - -}; - -unsigned num_std_regs = (sizeof std_regs / sizeof std_regs[0]); - -#endif - - -/* Begin counting arguments for a function call, - saving the data about any containing call. */ - -void -start_arglist () -{ - register struct funcall *new; - - new = (struct funcall *) xmalloc (sizeof (struct funcall)); - new->next = funcall_chain; - new->arglist_len = arglist_len; - arglist_len = 0; - funcall_chain = new; -} - -/* Return the number of arguments in a function call just terminated, - and restore the data for the containing function call. */ - -int -end_arglist () -{ - register int val = arglist_len; - register struct funcall *call = funcall_chain; - funcall_chain = call->next; - arglist_len = call->arglist_len; - free ((PTR)call); - return val; -} - -/* Free everything in the funcall chain. - Used when there is an error inside parsing. */ - -static void -free_funcalls () -{ - register struct funcall *call, *next; - - for (call = funcall_chain; call; call = next) - { - next = call->next; - free ((PTR)call); - } -} - -/* This page contains the functions for adding data to the struct expression - being constructed. */ - -/* Add one element to the end of the expression. */ - -/* To avoid a bug in the Sun 4 compiler, we pass things that can fit into - a register through here */ - -void -write_exp_elt (expelt) - union exp_element expelt; -{ - if (expout_ptr >= expout_size) - { - expout_size *= 2; - expout = (struct expression *) - xrealloc ((char *) expout, sizeof (struct expression) - + EXP_ELEM_TO_BYTES (expout_size)); - } - expout->elts[expout_ptr++] = expelt; -} - -void -write_exp_elt_opcode (expelt) - enum exp_opcode expelt; -{ - union exp_element tmp; - - tmp.opcode = expelt; - - write_exp_elt (tmp); -} - -void -write_exp_elt_sym (expelt) - struct symbol *expelt; -{ - union exp_element tmp; - - tmp.symbol = expelt; - - write_exp_elt (tmp); -} - -void -write_exp_elt_block (b) - struct block *b; -{ - union exp_element tmp; - tmp.block = b; - write_exp_elt (tmp); -} - -void -write_exp_elt_longcst (expelt) - LONGEST expelt; -{ - union exp_element tmp; - - tmp.longconst = expelt; - - write_exp_elt (tmp); -} - -void -write_exp_elt_dblcst (expelt) - double expelt; -{ - union exp_element tmp; - - tmp.doubleconst = expelt; - - write_exp_elt (tmp); -} - -void -write_exp_elt_type (expelt) - struct type *expelt; -{ - union exp_element tmp; - - tmp.type = expelt; - - write_exp_elt (tmp); -} - -void -write_exp_elt_intern (expelt) - struct internalvar *expelt; -{ - union exp_element tmp; - - tmp.internalvar = expelt; - - write_exp_elt (tmp); -} - -/* Add a string constant to the end of the expression. - - String constants are stored by first writing an expression element - that contains the length of the string, then stuffing the string - constant itself into however many expression elements are needed - to hold it, and then writing another expression element that contains - the length of the string. I.E. an expression element at each end of - the string records the string length, so you can skip over the - expression elements containing the actual string bytes from either - end of the string. Note that this also allows gdb to handle - strings with embedded null bytes, as is required for some languages. - - Don't be fooled by the fact that the string is null byte terminated, - this is strictly for the convenience of debugging gdb itself. Gdb - Gdb does not depend up the string being null terminated, since the - actual length is recorded in expression elements at each end of the - string. The null byte is taken into consideration when computing how - many expression elements are required to hold the string constant, of - course. */ - - -void -write_exp_string (str) - struct stoken str; -{ - register int len = str.length; - register int lenelt; - register char *strdata; - - /* Compute the number of expression elements required to hold the string - (including a null byte terminator), along with one expression element - at each end to record the actual string length (not including the - null byte terminator). */ - - lenelt = 2 + BYTES_TO_EXP_ELEM (len + 1); - - /* Ensure that we have enough available expression elements to store - everything. */ - - if ((expout_ptr + lenelt) >= expout_size) - { - expout_size = max (expout_size * 2, expout_ptr + lenelt + 10); - expout = (struct expression *) - xrealloc ((char *) expout, (sizeof (struct expression) - + EXP_ELEM_TO_BYTES (expout_size))); - } - - /* Write the leading length expression element (which advances the current - expression element index), then write the string constant followed by a - terminating null byte, and then write the trailing length expression - element. */ - - write_exp_elt_longcst ((LONGEST) len); - strdata = (char *) &expout->elts[expout_ptr]; - memcpy (strdata, str.ptr, len); - *(strdata + len) = '\0'; - expout_ptr += lenelt - 2; - write_exp_elt_longcst ((LONGEST) len); -} - -/* Add a bitstring constant to the end of the expression. - - Bitstring constants are stored by first writing an expression element - that contains the length of the bitstring (in bits), then stuffing the - bitstring constant itself into however many expression elements are - needed to hold it, and then writing another expression element that - contains the length of the bitstring. I.E. an expression element at - each end of the bitstring records the bitstring length, so you can skip - over the expression elements containing the actual bitstring bytes from - either end of the bitstring. */ - -void -write_exp_bitstring (str) - struct stoken str; -{ - register int bits = str.length; /* length in bits */ - register int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; - register int lenelt; - register char *strdata; - - /* Compute the number of expression elements required to hold the bitstring, - along with one expression element at each end to record the actual - bitstring length in bits. */ - - lenelt = 2 + BYTES_TO_EXP_ELEM (len); - - /* Ensure that we have enough available expression elements to store - everything. */ - - if ((expout_ptr + lenelt) >= expout_size) - { - expout_size = max (expout_size * 2, expout_ptr + lenelt + 10); - expout = (struct expression *) - xrealloc ((char *) expout, (sizeof (struct expression) - + EXP_ELEM_TO_BYTES (expout_size))); - } - - /* Write the leading length expression element (which advances the current - expression element index), then write the bitstring constant, and then - write the trailing length expression element. */ - - write_exp_elt_longcst ((LONGEST) bits); - strdata = (char *) &expout->elts[expout_ptr]; - memcpy (strdata, str.ptr, len); - expout_ptr += lenelt - 2; - write_exp_elt_longcst ((LONGEST) bits); -} - -/* Type that corresponds to the address given in a minimal symbol. */ - -static struct type *msymbol_addr_type; - -/* Add the appropriate elements for a minimal symbol to the end of - the expression. */ - -void -write_exp_msymbol (msymbol, text_symbol_type, data_symbol_type) - struct minimal_symbol *msymbol; - struct type *text_symbol_type; - struct type *data_symbol_type; -{ - write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (msymbol_addr_type); - write_exp_elt_longcst ((LONGEST) SYMBOL_VALUE_ADDRESS (msymbol)); - write_exp_elt_opcode (OP_LONG); - - write_exp_elt_opcode (UNOP_MEMVAL); - switch (msymbol -> type) - { - case mst_text: - case mst_file_text: - case mst_solib_trampoline: - write_exp_elt_type (text_symbol_type); - break; - - case mst_data: - case mst_file_data: - case mst_bss: - case mst_file_bss: - write_exp_elt_type (data_symbol_type); - break; - - default: - write_exp_elt_type (builtin_type_char); - break; - } - write_exp_elt_opcode (UNOP_MEMVAL); -} - -/* Return a null-terminated temporary copy of the name - of a string token. */ - -char * -copy_name (token) - struct stoken token; -{ - memcpy (namecopy, token.ptr, token.length); - namecopy[token.length] = 0; - return namecopy; -} - -/* Reverse an expression from suffix form (in which it is constructed) - to prefix form (in which we can conveniently print or execute it). */ - -static void -prefixify_expression (expr) - register struct expression *expr; -{ - register int len = - sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts); - register struct expression *temp; - register int inpos = expr->nelts, outpos = 0; - - temp = (struct expression *) alloca (len); - - /* Copy the original expression into temp. */ - memcpy (temp, expr, len); - - prefixify_subexp (temp, expr, inpos, outpos); -} - -/* Return the number of exp_elements in the subexpression of EXPR - whose last exp_element is at index ENDPOS - 1 in EXPR. */ - -static int -length_of_subexp (expr, endpos) - register struct expression *expr; - register int endpos; -{ - register int oplen = 1; - register int args = 0; - register int i; - - if (endpos < 1) - error ("?error in length_of_subexp"); - - i = (int) expr->elts[endpos - 1].opcode; - - switch (i) - { - /* C++ */ - case OP_SCOPE: - oplen = longest_to_int (expr->elts[endpos - 2].longconst); - oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1); - break; - - case OP_LONG: - case OP_DOUBLE: - case OP_VAR_VALUE: - oplen = 4; - break; - - case OP_TYPE: - case OP_BOOL: - case OP_LAST: - case OP_REGISTER: - case OP_INTERNALVAR: - oplen = 3; - break; - - case OP_FUNCALL: - oplen = 3; - args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); - break; - - case UNOP_MAX: - case UNOP_MIN: - oplen = 3; - break; - - case BINOP_VAL: - case UNOP_CAST: - case UNOP_MEMVAL: - oplen = 3; - args = 1; - break; - - case UNOP_ABS: - case UNOP_CAP: - case UNOP_CHR: - case UNOP_FLOAT: - case UNOP_HIGH: - case UNOP_ODD: - case UNOP_ORD: - case UNOP_TRUNC: - oplen = 1; - args = 1; - break; - - case STRUCTOP_STRUCT: - case STRUCTOP_PTR: - args = 1; - /* fall through */ - case OP_M2_STRING: - case OP_STRING: - oplen = longest_to_int (expr->elts[endpos - 2].longconst); - oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1); - break; - - case OP_BITSTRING: - oplen = longest_to_int (expr->elts[endpos - 2].longconst); - oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; - oplen = 4 + BYTES_TO_EXP_ELEM (oplen); - break; - - case OP_ARRAY: - oplen = 4; - args = longest_to_int (expr->elts[endpos - 2].longconst); - args -= longest_to_int (expr->elts[endpos - 3].longconst); - args += 1; - break; - - case TERNOP_COND: - args = 3; - break; - - /* Modula-2 */ - case MULTI_SUBSCRIPT: - oplen=3; - args = 1 + longest_to_int (expr->elts[endpos- 2].longconst); - break; - - case BINOP_ASSIGN_MODIFY: - oplen = 3; - args = 2; - break; - - /* C++ */ - case OP_THIS: - oplen = 2; - break; - - default: - args = 1 + (i < (int) BINOP_END); - } - - while (args > 0) - { - oplen += length_of_subexp (expr, endpos - oplen); - args--; - } - - return oplen; -} - -/* Copy the subexpression ending just before index INEND in INEXPR - into OUTEXPR, starting at index OUTBEG. - In the process, convert it from suffix to prefix form. */ - -static void -prefixify_subexp (inexpr, outexpr, inend, outbeg) - register struct expression *inexpr; - struct expression *outexpr; - register int inend; - int outbeg; -{ - register int oplen = 1; - register int args = 0; - register int i; - int *arglens; - enum exp_opcode opcode; - - /* Compute how long the last operation is (in OPLEN), - and also how many preceding subexpressions serve as - arguments for it (in ARGS). */ - - opcode = inexpr->elts[inend - 1].opcode; - switch (opcode) - { - /* C++ */ - case OP_SCOPE: - oplen = longest_to_int (inexpr->elts[inend - 2].longconst); - oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1); - break; - - case OP_LONG: - case OP_DOUBLE: - case OP_VAR_VALUE: - oplen = 4; - break; - - case OP_TYPE: - case OP_BOOL: - case OP_LAST: - case OP_REGISTER: - case OP_INTERNALVAR: - oplen = 3; - break; - - case OP_FUNCALL: - oplen = 3; - args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst); - break; - - case UNOP_MIN: - case UNOP_MAX: - oplen = 3; - break; - - case UNOP_CAST: - case UNOP_MEMVAL: - oplen = 3; - args = 1; - break; - - case UNOP_ABS: - case UNOP_CAP: - case UNOP_CHR: - case UNOP_FLOAT: - case UNOP_HIGH: - case UNOP_ODD: - case UNOP_ORD: - case UNOP_TRUNC: - oplen=1; - args=1; - break; - - case STRUCTOP_STRUCT: - case STRUCTOP_PTR: - args = 1; - /* fall through */ - case OP_M2_STRING: - case OP_STRING: - oplen = longest_to_int (inexpr->elts[inend - 2].longconst); - oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1); - break; - - case OP_BITSTRING: - oplen = longest_to_int (inexpr->elts[inend - 2].longconst); - oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; - oplen = 4 + BYTES_TO_EXP_ELEM (oplen); - break; - - case OP_ARRAY: - oplen = 4; - args = longest_to_int (inexpr->elts[inend - 2].longconst); - args -= longest_to_int (inexpr->elts[inend - 3].longconst); - args += 1; - break; - - case TERNOP_COND: - args = 3; - break; - - case BINOP_ASSIGN_MODIFY: - oplen = 3; - args = 2; - break; - - /* Modula-2 */ - case MULTI_SUBSCRIPT: - oplen=3; - args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst); - break; - - /* C++ */ - case OP_THIS: - oplen = 2; - break; - - default: - args = 1 + ((int) opcode < (int) BINOP_END); - } - - /* Copy the final operator itself, from the end of the input - to the beginning of the output. */ - inend -= oplen; - memcpy (&outexpr->elts[outbeg], &inexpr->elts[inend], - EXP_ELEM_TO_BYTES (oplen)); - outbeg += oplen; - - /* Find the lengths of the arg subexpressions. */ - arglens = (int *) alloca (args * sizeof (int)); - for (i = args - 1; i >= 0; i--) - { - oplen = length_of_subexp (inexpr, inend); - arglens[i] = oplen; - inend -= oplen; - } - - /* Now copy each subexpression, preserving the order of - the subexpressions, but prefixifying each one. - In this loop, inend starts at the beginning of - the expression this level is working on - and marches forward over the arguments. - outbeg does similarly in the output. */ - for (i = 0; i < args; i++) - { - oplen = arglens[i]; - inend += oplen; - prefixify_subexp (inexpr, outexpr, inend, outbeg); - outbeg += oplen; - } -} - -/* This page contains the two entry points to this file. */ - -/* Read an expression from the string *STRINGPTR points to, - parse it, and return a pointer to a struct expression that we malloc. - Use block BLOCK as the lexical context for variable names; - if BLOCK is zero, use the block of the selected stack frame. - Meanwhile, advance *STRINGPTR to point after the expression, - at the first nonwhite character that is not part of the expression - (possibly a null character). - - If COMMA is nonzero, stop if a comma is reached. */ - -struct expression * -parse_exp_1 (stringptr, block, comma) - char **stringptr; - struct block *block; - int comma; -{ - struct cleanup *old_chain; - - lexptr = *stringptr; - - paren_depth = 0; - type_stack_depth = 0; - - comma_terminates = comma; - - if (lexptr == 0 || *lexptr == 0) - error_no_arg ("expression to compute"); - - old_chain = make_cleanup (free_funcalls, 0); - funcall_chain = 0; - - expression_context_block = block ? block : get_selected_block (); - - namecopy = (char *) alloca (strlen (lexptr) + 1); - expout_size = 10; - expout_ptr = 0; - expout = (struct expression *) - xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size)); - expout->language_defn = current_language; - make_cleanup (free_current_contents, &expout); - - if (current_language->la_parser ()) - current_language->la_error (NULL); - - discard_cleanups (old_chain); - - /* Record the actual number of expression elements, and then - reallocate the expression memory so that we free up any - excess elements. */ - - expout->nelts = expout_ptr; - expout = (struct expression *) - xrealloc ((char *) expout, - sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_ptr));; - - /* Convert expression from postfix form as generated by yacc - parser, to a prefix form. */ - - DUMP_EXPRESSION (expout, gdb_stdout, "before conversion to prefix form"); - prefixify_expression (expout); - DUMP_EXPRESSION (expout, gdb_stdout, "after conversion to prefix form"); - - *stringptr = lexptr; - return expout; -} - -/* Parse STRING as an expression, and complain if this fails - to use up all of the contents of STRING. */ - -struct expression * -parse_expression (string) - char *string; -{ - register struct expression *exp; - exp = parse_exp_1 (&string, 0, 0); - if (*string) - error ("Junk after end of expression."); - return exp; -} - -/* Stuff for maintaining a stack of types. Currently just used by C, but - probably useful for any language which declares its types "backwards". */ - -void -push_type (tp) - enum type_pieces tp; -{ - if (type_stack_depth == type_stack_size) - { - type_stack_size *= 2; - type_stack = (union type_stack_elt *) - xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack)); - } - type_stack[type_stack_depth++].piece = tp; -} - -void -push_type_int (n) - int n; -{ - if (type_stack_depth == type_stack_size) - { - type_stack_size *= 2; - type_stack = (union type_stack_elt *) - xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack)); - } - type_stack[type_stack_depth++].int_val = n; -} - -enum type_pieces -pop_type () -{ - if (type_stack_depth) - return type_stack[--type_stack_depth].piece; - return tp_end; -} - -int -pop_type_int () -{ - if (type_stack_depth) - return type_stack[--type_stack_depth].int_val; - /* "Can't happen". */ - return 0; -} - -/* Pop the type stack and return the type which corresponds to FOLLOW_TYPE - as modified by all the stuff on the stack. */ -struct type * -follow_types (follow_type) - struct type *follow_type; -{ - int done = 0; - int array_size; - struct type *range_type; - - while (!done) - switch (pop_type ()) - { - case tp_end: - done = 1; - break; - case tp_pointer: - follow_type = lookup_pointer_type (follow_type); - break; - case tp_reference: - follow_type = lookup_reference_type (follow_type); - break; - case tp_array: - array_size = pop_type_int (); - if (array_size != -1) - { - range_type = - create_range_type ((struct type *) NULL, - builtin_type_int, 0, - array_size - 1); - follow_type = - create_array_type ((struct type *) NULL, - follow_type, range_type); - } - else - follow_type = lookup_pointer_type (follow_type); - break; - case tp_function: - follow_type = lookup_function_type (follow_type); - break; - } - return follow_type; -} - -void -_initialize_parse () -{ - type_stack_size = 80; - type_stack_depth = 0; - type_stack = (union type_stack_elt *) - xmalloc (type_stack_size * sizeof (*type_stack)); - - /* We don't worry too much about what the name of this type is - because the name should rarely appear in output to the user. */ - - msymbol_addr_type = - init_type (TYPE_CODE_PTR, TARGET_PTR_BIT / HOST_CHAR_BIT, 0, - "void *", NULL); -} diff --git a/gnu/usr.bin/gdb/gdb/parser-defs.h b/gnu/usr.bin/gdb/gdb/parser-defs.h deleted file mode 100644 index 67ba0c3..0000000 --- a/gnu/usr.bin/gdb/gdb/parser-defs.h +++ /dev/null @@ -1,186 +0,0 @@ -/* Parser definitions for GDB. - Copyright (C) 1986, 1989, 1990, 1991 Free Software Foundation, Inc. - Modified from expread.y by the Department of Computer Science at the - State University of New York at Buffalo. - -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 (PARSER_DEFS_H) -#define PARSER_DEFS_H 1 - -struct std_regs { - char *name; - int regnum; -}; - -extern struct std_regs std_regs[]; -extern unsigned num_std_regs; - -extern struct expression *expout; -extern int expout_size; -extern int expout_ptr; - -/* If this is nonzero, this block is used as the lexical context - for symbol names. */ - -extern struct block *expression_context_block; - -/* The innermost context required by the stack and register variables - we've encountered so far. */ -extern struct block *innermost_block; - -/* The block in which the most recently discovered symbol was found. - FIXME: Should be declared along with lookup_symbol in symtab.h; is not - related specifically to parsing. */ -extern struct block *block_found; - -/* Number of arguments seen so far in innermost function call. */ -extern int arglist_len; - -/* A string token, either a char-string or bit-string. Char-strings are - used, for example, for the names of symbols. */ - -struct stoken - { - /* Pointer to first byte of char-string or first bit of bit-string */ - char *ptr; - /* Length of string in bytes for char-string or bits for bit-string */ - int length; - }; - -struct ttype - { - struct stoken stoken; - struct type *type; - }; - -struct symtoken - { - struct stoken stoken; - struct symbol *sym; - int is_a_field_of_this; - }; - -/* For parsing of complicated types. - An array should be preceded in the list by the size of the array. */ -enum type_pieces - {tp_end = -1, tp_pointer, tp_reference, tp_array, tp_function}; -/* The stack can contain either an enum type_pieces or an int. */ -union type_stack_elt { - enum type_pieces piece; - int int_val; -}; -extern union type_stack_elt *type_stack; -extern int type_stack_depth, type_stack_size; - -extern void write_exp_elt PARAMS ((union exp_element)); - -extern void write_exp_elt_opcode PARAMS ((enum exp_opcode)); - -extern void write_exp_elt_sym PARAMS ((struct symbol *)); - -extern void write_exp_elt_longcst PARAMS ((LONGEST)); - -extern void write_exp_elt_dblcst PARAMS ((double)); - -extern void write_exp_elt_type PARAMS ((struct type *)); - -extern void write_exp_elt_intern PARAMS ((struct internalvar *)); - -extern void write_exp_string PARAMS ((struct stoken)); - -extern void write_exp_bitstring PARAMS ((struct stoken)); - -extern void write_exp_elt_block PARAMS ((struct block *)); - -extern void write_exp_msymbol PARAMS ((struct minimal_symbol *, - struct type *, struct type *)); - -extern void -start_arglist PARAMS ((void)); - -extern int -end_arglist PARAMS ((void)); - -extern char * -copy_name PARAMS ((struct stoken)); - -extern void -push_type PARAMS ((enum type_pieces)); - -extern void -push_type_int PARAMS ((int)); - -extern enum type_pieces -pop_type PARAMS ((void)); - -extern int -pop_type_int PARAMS ((void)); - -extern struct type *follow_types PARAMS ((struct type *)); - -/* During parsing of a C expression, the pointer to the next character - is in this variable. */ - -extern char *lexptr; - -/* Tokens that refer to names do so with explicit pointer and length, - so they can share the storage that lexptr is parsing. - - When it is necessary to pass a name to a function that expects - a null-terminated string, the substring is copied out - into a block of storage that namecopy points to. - - namecopy is allocated once, guaranteed big enough, for each parsing. */ - -extern char *namecopy; - -/* Current depth in parentheses within the expression. */ - -extern int paren_depth; - -/* Nonzero means stop parsing on first comma (if not within parentheses). */ - -extern int comma_terminates; - -/* These codes indicate operator precedences for expression printing, - least tightly binding first. */ -/* Adding 1 to a precedence value is done for binary operators, - on the operand which is more tightly bound, so that operators - of equal precedence within that operand will get parentheses. */ -/* PREC_HYPER and PREC_ABOVE_COMMA are not the precedence of any operator; - they are used as the "surrounding precedence" to force - various kinds of things to be parenthesized. */ -enum precedence -{ PREC_NULL, PREC_COMMA, PREC_ABOVE_COMMA, PREC_ASSIGN, PREC_LOGICAL_OR, - PREC_LOGICAL_AND, PREC_BITWISE_IOR, PREC_BITWISE_AND, PREC_BITWISE_XOR, - PREC_EQUAL, PREC_ORDER, PREC_SHIFT, PREC_ADD, PREC_MUL, PREC_REPEAT, - PREC_HYPER, PREC_PREFIX, PREC_SUFFIX }; - -/* Table mapping opcodes into strings for printing operators - and precedences of the operators. */ - -struct op_print -{ - char *string; - enum exp_opcode opcode; - /* Precedence of operator. These values are used only by comparisons. */ - enum precedence precedence; - int right_assoc; -}; - -#endif /* PARSER_DEFS_H */ diff --git a/gnu/usr.bin/gdb/gdb/partial-stab.h b/gnu/usr.bin/gdb/gdb/partial-stab.h deleted file mode 100644 index 2f15423..0000000 --- a/gnu/usr.bin/gdb/gdb/partial-stab.h +++ /dev/null @@ -1,679 +0,0 @@ -/* Shared code to pre-read a stab (dbx-style), when building a psymtab. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 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. */ - -/* The following need to be defined: - SET_NAMESTRING() --Set namestring to name of symbol. - CUR_SYMBOL_TYPE --Type code of current symbol. - CUR_SYMBOL_VALUE --Value field of current symbol. May be adjusted here. - */ - -/* End of macro definitions, now let's handle them symbols! */ - - switch (CUR_SYMBOL_TYPE) - { - char *p; - /* - * Standard, external, non-debugger, symbols - */ - - case N_TEXT | N_EXT: - case N_NBTEXT | N_EXT: - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); - goto record_it; - - case N_DATA | N_EXT: - case N_NBDATA | N_EXT: - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); - goto record_it; - - case N_BSS: - case N_BSS | N_EXT: - case N_NBBSS | N_EXT: - case N_SETV | N_EXT: /* FIXME, is this in BSS? */ - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_BSS); - goto record_it; - - case N_ABS | N_EXT: - record_it: -#ifdef DBXREAD_ONLY - SET_NAMESTRING(); - - bss_ext_symbol: - record_minimal_symbol (namestring, CUR_SYMBOL_VALUE, - CUR_SYMBOL_TYPE, objfile); /* Always */ -#endif /* DBXREAD_ONLY */ - continue; - - /* Standard, local, non-debugger, symbols */ - - case N_NBTEXT: - - /* We need to be able to deal with both N_FN or N_TEXT, - because we have no way of knowing whether the sys-supplied ld - or GNU ld was used to make the executable. Sequents throw - in another wrinkle -- they renumbered N_FN. */ - - case N_FN: - case N_FN_SEQ: - case N_TEXT: -#ifdef DBXREAD_ONLY - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); - SET_NAMESTRING(); - if ((namestring[0] == '-' && namestring[1] == 'l') - || (namestring [(nsl = strlen (namestring)) - 1] == 'o' - && namestring [nsl - 2] == '.') -#ifdef GDB_TARGET_IS_HPPA - /* some cooperation from gcc to get around ld stupidity */ - || (namestring[0] == 'e' && STREQ (namestring, "end_file.")) -#endif - ) - { -#ifndef GDB_TARGET_IS_HPPA - if (objfile -> ei.entry_point < CUR_SYMBOL_VALUE && - objfile -> ei.entry_point >= last_o_file_start) - { - objfile -> ei.entry_file_lowpc = last_o_file_start; - objfile -> ei.entry_file_highpc = CUR_SYMBOL_VALUE; - } -#endif - if (past_first_source_file && pst - /* The gould NP1 uses low values for .o and -l symbols - which are not the address. */ - && CUR_SYMBOL_VALUE >= pst->textlow) - { - END_PSYMTAB (pst, psymtab_include_list, includes_used, - symnum * symbol_size, CUR_SYMBOL_VALUE, - dependency_list, dependencies_used); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; - } - else - past_first_source_file = 1; - last_o_file_start = CUR_SYMBOL_VALUE; - } - else - goto record_it; -#endif /* DBXREAD_ONLY */ - continue; - - case N_DATA: - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); - goto record_it; - - case N_UNDF | N_EXT: -#ifdef DBXREAD_ONLY - if (CUR_SYMBOL_VALUE != 0) { - /* This is a "Fortran COMMON" symbol. See if the target - environment knows where it has been relocated to. */ - - CORE_ADDR reladdr; - - SET_NAMESTRING(); - if (target_lookup_symbol (namestring, &reladdr)) { - continue; /* Error in lookup; ignore symbol for now. */ - } - CUR_SYMBOL_TYPE ^= (N_BSS^N_UNDF); /* Define it as a bss-symbol */ - CUR_SYMBOL_VALUE = reladdr; - goto bss_ext_symbol; - } -#endif /* DBXREAD_ONLY */ - continue; /* Just undefined, not COMMON */ - - case N_UNDF: -#ifdef DBXREAD_ONLY - if (processing_acc_compilation && bufp->n_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, - we must adjust file_string_table_offset *before* calling - SET_NAMESTRING(). */ - 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; - if (next_file_string_table_offset < file_string_table_offset) - error ("string table offset backs up at %d", symnum); - /* FIXME -- replace error() with complaint. */ - continue; - } -#endif /* DBXREAD_ONLY */ - continue; - - /* Lots of symbol types we can just ignore. */ - - case N_ABS: - case N_NBDATA: - case N_NBBSS: - continue; - - /* Keep going . . .*/ - - /* - * Special symbol types for GNU - */ - case N_INDR: - case N_INDR | N_EXT: - case N_SETA: - case N_SETA | N_EXT: - case N_SETT: - case N_SETT | N_EXT: - case N_SETD: - case N_SETD | N_EXT: - case N_SETB: - case N_SETB | N_EXT: - case N_SETV: - continue; - - /* - * Debugger symbols - */ - - case N_SO: { - unsigned long valu; - static int prev_so_symnum = -10; - static int first_so_symnum; - char *p; - - valu = CUR_SYMBOL_VALUE + ANOFFSET (section_offsets, SECT_OFF_TEXT); - - past_first_source_file = 1; - - if (prev_so_symnum != symnum - 1) - { /* Here if prev stab wasn't N_SO */ - first_so_symnum = symnum; - - if (pst) - { - END_PSYMTAB (pst, psymtab_include_list, includes_used, - symnum * symbol_size, valu, - dependency_list, dependencies_used); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; - } - } - - prev_so_symnum = symnum; - - /* End the current partial symtab and start a new one */ - - SET_NAMESTRING(); - - /* Some compilers (including gcc) emit a pair of initial N_SOs. - The first one is a directory name; the second the file name. - If pst exists, is empty, and has a filename ending in '/', - we assume the previous N_SO was a directory name. */ - - p = strrchr (namestring, '/'); - if (p && *(p+1) == '\000') - continue; /* Simply ignore directory name SOs */ - - /* Some other compilers (C++ ones in particular) emit useless - SOs for non-existant .c files. We ignore all subsequent SOs that - immediately follow the first. */ - - if (!pst) - pst = START_PSYMTAB (objfile, section_offsets, - namestring, valu, - first_so_symnum * symbol_size, - objfile -> global_psymbols.next, - objfile -> static_psymbols.next); - continue; - } - - case N_BINCL: - { -#ifdef DBXREAD_ONLY - enum language tmp_language; - /* Add this bincl to the bincl_list for future EXCLs. No - need to save the string; it'll be around until - read_dbx_symtab function returns */ - - SET_NAMESTRING(); - - tmp_language = deduce_language_from_filename (namestring); - - /* Only change the psymtab's language if we've learned - something useful (eg. tmp_language is not language_unknown). - In addition, to match what start_subfile does, never change - from C++ to C. */ - if (tmp_language != language_unknown - && (tmp_language != language_c - || psymtab_language != language_cplus)) - psymtab_language = tmp_language; - - add_bincl_to_list (pst, namestring, CUR_SYMBOL_VALUE); - - /* Mark down an include file in the current psymtab */ - - goto record_include_file; - -#else /* DBXREAD_ONLY */ - continue; -#endif - } - - case N_SOL: - { - enum language tmp_language; - /* Mark down an include file in the current psymtab */ - - SET_NAMESTRING(); - - tmp_language = deduce_language_from_filename (namestring); - - /* Only change the psymtab's language if we've learned - something useful (eg. tmp_language is not language_unknown). - In addition, to match what start_subfile does, never change - from C++ to C. */ - if (tmp_language != language_unknown - && (tmp_language != language_c - || psymtab_language != language_cplus)) - psymtab_language = tmp_language; - - /* In C++, one may expect the same filename to come round many - times, when code is coming alternately from the main file - and from inline functions in other files. So I check to see - if this is a file we've seen before -- either the main - source file, or a previously included file. - - This seems to be a lot of time to be spending on N_SOL, but - things like "break c-exp.y:435" need to work (I - suppose the psymtab_include_list could be hashed or put - in a binary tree, if profiling shows this is a major hog). */ - if (pst && STREQ (namestring, pst->filename)) - continue; - { - register int i; - for (i = 0; i < includes_used; i++) - if (STREQ (namestring, psymtab_include_list[i])) - { - i = -1; - break; - } - if (i == -1) - continue; - } - -#ifdef DBXREAD_ONLY - record_include_file: -#endif - - 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; - } - case N_LSYM: /* Typedef or automatic variable. */ - case N_STSYM: /* Data seg var -- static */ - case N_LCSYM: /* BSS " */ - case N_ROSYM: /* Read-only data seg var -- static. */ - case N_NBSTS: /* Gould nobase. */ - case N_NBLCS: /* symbols. */ - case N_FUN: - case N_GSYM: /* Global (extern) variable; can be - data or bss (sigh FIXME). */ - - /* Following may probably be ignored; I'll leave them here - for now (until I do Pascal and Modula 2 extensions). */ - - case N_PC: /* I may or may not need this; I - suspect not. */ - case N_M2C: /* I suspect that I can ignore this here. */ - case N_SCOPE: /* Same. */ - - SET_NAMESTRING(); - - p = (char *) strchr (namestring, ':'); - if (!p) - continue; /* Not a debugging symbol. */ - - - - /* Main processing section for debugging symbols which - the initial read through the symbol tables needs to worry - about. If we reach this point, the symbol which we are - considering is definitely one we are interested in. - p must also contain the (valid) index into the namestring - which indicates the debugging type symbol. */ - - switch (p[1]) - { - case 'S': - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); - ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - objfile->static_psymbols, - CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - case 'G': - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA); - /* The addresses in these entries are reported to be - wrong. See the code that reads 'G's for symtabs. */ - ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - objfile->global_psymbols, - CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - - case 'T': - if (p != namestring) /* a name is there, not just :T... */ - { - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - STRUCT_NAMESPACE, LOC_TYPEDEF, - objfile->static_psymbols, - CUR_SYMBOL_VALUE, - psymtab_language, objfile); - if (p[2] == 't') - { - /* Also a typedef with the same name. */ - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - objfile->static_psymbols, - CUR_SYMBOL_VALUE, psymtab_language, - objfile); - p += 1; - } - /* The semantics of C++ state that "struct foo { ... }" - also defines a typedef for "foo". Unfortuantely, cfront - never makes the typedef when translating from C++ to C. - We make the typedef here so that "ptype foo" works as - expected for cfront translated code. */ - else if (psymtab_language == language_cplus) - { - /* Also a typedef with the same name. */ - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - objfile->static_psymbols, - CUR_SYMBOL_VALUE, psymtab_language, - objfile); - } - } - goto check_enum; - case 't': - if (p != namestring) /* a name is there, not just :T... */ - { - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - objfile->static_psymbols, - CUR_SYMBOL_VALUE, - psymtab_language, objfile); - } - check_enum: - /* If this is an enumerated type, we need to - add all the enum constants to the partial symbol - table. This does not cover enums without names, e.g. - "enum {a, b} c;" in C, but fortunately those are - rare. There is no way for GDB to find those from the - enum type without spending too much time on it. Thus - to solve this problem, the compiler needs to put out the - enum in a nameless type. GCC2 does this. */ - - /* We are looking for something of the form - ":" ("t" | "T") [ "="] "e" - { ":" ","} ";". */ - - /* Skip over the colon and the 't' or 'T'. */ - p += 2; - /* This type may be given a number. Also, numbers can come - in pairs like (0,26). Skip over it. */ - while ((*p >= '0' && *p <= '9') - || *p == '(' || *p == ',' || *p == ')' - || *p == '=') - p++; - - if (*p++ == 'e') - { - /* We have found an enumerated type. */ - /* According to comments in read_enum_type - a comma could end it instead of a semicolon. - I don't know where that happens. - Accept either. */ - while (*p && *p != ';' && *p != ',') - { - char *q; - - /* Check for and handle cretinous dbx symbol name - continuation! */ - if (*p == '\\' || (*p == '?' && p[1] == '\0')) - p = next_symbol_text (); - - /* Point to the character after the name - of the enum constant. */ - for (q = p; *q && *q != ':'; q++) - ; - /* Note that the value doesn't matter for - enum constants in psymtabs, just in symtabs. */ - ADD_PSYMBOL_TO_LIST (p, q - p, - VAR_NAMESPACE, LOC_CONST, - objfile->static_psymbols, 0, - psymtab_language, objfile); - /* Point past the name. */ - p = q; - /* Skip over the value. */ - while (*p && *p != ',') - p++; - /* Advance past the comma. */ - if (*p) - p++; - } - } - continue; - case 'c': - /* Constant, e.g. from "const" in Pascal. */ - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_CONST, - objfile->static_psymbols, CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - - case 'f': - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); -#ifdef DBXREAD_ONLY - /* Kludges for ELF/STABS with Sun ACC */ - last_function_name = namestring; - /* 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 = CUR_SYMBOL_VALUE; -#if 0 - if (startup_file_end == 0) - startup_file_end = CUR_SYMBOL_VALUE; -#endif - /* End kludge. */ -#endif /* DBXREAD_ONLY */ - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - objfile->static_psymbols, CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - - /* Global functions were ignored here, but now they - are put into the global psymtab like one would expect. - They're also in the minimal symbol table. */ - case 'F': - CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT); -#ifdef DBXREAD_ONLY - /* Kludges for ELF/STABS with Sun ACC */ - last_function_name = namestring; - /* 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 = CUR_SYMBOL_VALUE; -#if 0 - if (startup_file_end == 0) - startup_file_end = CUR_SYMBOL_VALUE; -#endif - /* End kludge. */ -#endif /* DBXREAD_ONLY */ - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - objfile->global_psymbols, CUR_SYMBOL_VALUE, - psymtab_language, objfile); - continue; - - /* Two things show up here (hopefully); static symbols of - local scope (static used inside braces) or extensions - of structure symbols. We can ignore both. */ - case 'V': - case '(': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - continue; - - case ':': - /* It is a C++ nested symbol. We don't need to record it - (I don't think); if we try to look up foo::bar::baz, - then symbols for the symtab containing foo should get - read in, I think. */ - /* Someone says sun cc puts out symbols like - /foo/baz/maclib::/usr/local/bin/maclib, - which would get here with a symbol type of ':'. */ - continue; - - default: - /* Unexpected symbol descriptor. The second and subsequent stabs - of a continued stab can show up here. The question is - whether they ever can mimic a normal stab--it would be - nice if not, since we certainly don't want to spend the - time searching to the end of every string looking for - a backslash. */ - - complain (&unknown_symchar_complaint, p[1]); - - /* Ignore it; perhaps it is an extension that we don't - know about. */ - continue; - } - - case N_EXCL: -#ifdef DBXREAD_ONLY - - SET_NAMESTRING(); - - /* Find the corresponding bincl and mark that psymtab on the - psymtab dependency list */ - { - struct partial_symtab *needed_pst = - find_corresponding_bincl_psymtab (namestring, CUR_SYMBOL_VALUE); - - /* If this include file was defined earlier in this file, - leave it alone. */ - if (needed_pst == pst) continue; - - if (needed_pst) - { - int i; - int found = 0; - - for (i = 0; i < dependencies_used; i++) - if (dependency_list[i] == needed_pst) - { - found = 1; - break; - } - - /* If it's already in the list, skip the rest. */ - if (found) continue; - - dependency_list[dependencies_used++] = needed_pst; - if (dependencies_used >= dependencies_allocated) - { - struct partial_symtab **orig = dependency_list; - dependency_list = - (struct partial_symtab **) - alloca ((dependencies_allocated *= 2) - * sizeof (struct partial_symtab *)); - memcpy ((PTR)dependency_list, (PTR)orig, - (dependencies_used - * sizeof (struct partial_symtab *))); -#ifdef DEBUG_INFO - fprintf_unfiltered (gdb_stderr, "Had to reallocate dependency list.\n"); - fprintf_unfiltered (gdb_stderr, "New dependencies allocated: %d\n", - dependencies_allocated); -#endif - } - } - else - error ("Invalid symbol data: \"repeated\" header file not previously seen, at symtab pos %d.", - symnum); - } -#endif /* DBXREAD_ONLY */ - continue; - - case N_RBRAC: -#ifdef HANDLE_RBRAC - HANDLE_RBRAC(CUR_SYMBOL_VALUE); - continue; -#endif - case N_EINCL: - case N_DSLINE: - case N_BSLINE: - case N_SSYM: /* Claim: Structure or union element. - Hopefully, I can ignore this. */ - case N_ENTRY: /* Alternate entry point; can ignore. */ - case N_MAIN: /* Can definitely ignore this. */ - case N_CATCH: /* These are GNU C++ extensions */ - case N_EHDECL: /* that can safely be ignored here. */ - case N_LENG: - case N_BCOMM: - case N_ECOMM: - case N_ECOML: - case N_FNAME: - case N_SLINE: - case N_RSYM: - case N_PSYM: - case N_LBRAC: - case N_NSYMS: /* Ultrix 4.0: symbol count */ - case N_DEFD: /* GNU Modula-2 */ - - case N_OBJ: /* useless types from Solaris */ - case N_OPT: - case N_ENDM: - /* These symbols aren't interesting; don't worry about them */ - - continue; - - default: - /* If we haven't found it yet, ignore it. It's probably some - new type we don't know about yet. */ - complain (&unknown_symtype_complaint, - local_hex_string (CUR_SYMBOL_TYPE)); - continue; - } diff --git a/gnu/usr.bin/gdb/gdb/printcmd.c b/gnu/usr.bin/gdb/gdb/printcmd.c deleted file mode 100644 index 1f81bc9..0000000 --- a/gnu/usr.bin/gdb/gdb/printcmd.c +++ /dev/null @@ -1,2220 +0,0 @@ -/* Print values for GNU debugger GDB. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 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. */ - -#include "defs.h" -#include -#include -#include "frame.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "value.h" -#include "language.h" -#include "expression.h" -#include "gdbcore.h" -#include "gdbcmd.h" -#include "target.h" -#include "breakpoint.h" -#include "demangle.h" -#include "valprint.h" -#include "annotate.h" - -extern int asm_demangle; /* Whether to demangle syms in asm printouts */ -extern int addressprint; /* Whether to print hex addresses in HLL " */ - -struct format_data -{ - int count; - char format; - char size; -}; - -/* Last specified output format. */ - -static char last_format = 'x'; - -/* Last specified examination size. 'b', 'h', 'w' or `q'. */ - -static char last_size = 'w'; - -/* Default address to examine next. */ - -static CORE_ADDR next_address; - -/* Last address examined. */ - -static CORE_ADDR last_examine_address; - -/* Contents of last address examined. - This is not valid past the end of the `x' command! */ - -static value_ptr last_examine_value; - -/* Largest offset between a symbolic value and an address, that will be - printed as `0x1234 '. */ - -static unsigned int max_symbolic_offset = UINT_MAX; - -/* Append the source filename and linenumber of the symbol when - printing a symbolic value as `' if set. */ -static int print_symbol_filename = 0; - -/* Number of auto-display expression currently being displayed. - So that we can disable it if we get an error or a signal within it. - -1 when not doing one. */ - -int current_display_number; - -/* Flag to low-level print routines that this value is being printed - in an epoch window. We'd like to pass this as a parameter, but - every routine would need to take it. Perhaps we can encapsulate - this in the I/O stream once we have GNU stdio. */ - -int inspect_it = 0; - -struct display -{ - /* Chain link to next auto-display item. */ - struct display *next; - /* Expression to be evaluated and displayed. */ - struct expression *exp; - /* Item number of this auto-display item. */ - int number; - /* Display format specified. */ - struct format_data format; - /* Innermost block required by this expression when evaluated */ - struct block *block; - /* Status of this display (enabled or disabled) */ - enum enable status; -}; - -/* Chain of expressions whose values should be displayed - automatically each time the program stops. */ - -static struct display *display_chain; - -static int display_number; - -/* Prototypes for local functions */ - -static void -delete_display PARAMS ((int)); - -static void -enable_display PARAMS ((char *, int)); - -static void -disable_display_command PARAMS ((char *, int)); - -static void -disassemble_command PARAMS ((char *, int)); - -static void -printf_command PARAMS ((char *, int)); - -static void -print_frame_nameless_args PARAMS ((struct frame_info *, long, int, int, - GDB_FILE *)); - -static void -display_info PARAMS ((char *, int)); - -static void -do_one_display PARAMS ((struct display *)); - -static void -undisplay_command PARAMS ((char *, int)); - -static void -free_display PARAMS ((struct display *)); - -static void -display_command PARAMS ((char *, int)); - -static 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)); - -static void -print_command PARAMS ((char *, int)); - -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 -print_formatted PARAMS ((value_ptr, int, int)); - -static struct format_data -decode_format PARAMS ((char **, int, int)); - - -/* Decode a format specification. *STRING_PTR should point to it. - OFORMAT and OSIZE are used as defaults for the format and size - if none are given in the format specification. - If OSIZE is zero, then the size field of the returned value - should be set only if a size is explicitly specified by the - user. - The structure returned describes all the data - found in the specification. In addition, *STRING_PTR is advanced - past the specification and past all whitespace following it. */ - -static struct format_data -decode_format (string_ptr, oformat, osize) - char **string_ptr; - int oformat; - int osize; -{ - struct format_data val; - register char *p = *string_ptr; - - val.format = '?'; - val.size = '?'; - val.count = 1; - - if (*p >= '0' && *p <= '9') - val.count = atoi (p); - while (*p >= '0' && *p <= '9') p++; - - /* Now process size or format letters that follow. */ - - while (1) - { - if (*p == 'b' || *p == 'h' || *p == 'w' || *p == 'g') - val.size = *p++; - else if (*p >= 'a' && *p <= 'z') - val.format = *p++; - else - break; - } - - while (*p == ' ' || *p == '\t') p++; - *string_ptr = p; - - /* Set defaults for format and size if not specified. */ - if (val.format == '?') - { - if (val.size == '?') - { - /* Neither has been specified. */ - val.format = oformat; - val.size = osize; - } - else - /* If a size is specified, any format makes a reasonable - default except 'i'. */ - val.format = oformat == 'i' ? 'x' : oformat; - } - else if (val.size == '?') - switch (val.format) - { - case 'a': - case 's': - /* Pick the appropriate size for an address. */ - if (TARGET_PTR_BIT == 64) - val.size = osize ? 'g' : osize; - else if (TARGET_PTR_BIT == 32) - val.size = osize ? 'w' : osize; - else if (TARGET_PTR_BIT == 16) - val.size = osize ? 'h' : osize; - else - /* Bad value for TARGET_PTR_BIT */ - abort (); - break; - case 'f': - /* Floating point has to be word or giantword. */ - if (osize == 'w' || osize == 'g') - val.size = osize; - else - /* Default it to giantword if the last used size is not - appropriate. */ - val.size = osize ? 'g' : osize; - break; - case 'c': - /* Characters default to one byte. */ - val.size = osize ? 'b' : osize; - break; - default: - /* The default is the size most recently specified. */ - val.size = osize; - } - - return val; -} - -/* Print value VAL on gdb_stdout according to FORMAT, a letter or 0. - Do not end with a newline. - 0 means print VAL according to its own type. - SIZE is the letter for the size of datum being printed. - This is used to pad hex numbers so they line up. */ - -static void -print_formatted (val, format, size) - register value_ptr val; - register int format; - int size; -{ - int len = TYPE_LENGTH (VALUE_TYPE (val)); - - if (VALUE_LVAL (val) == lval_memory) - next_address = VALUE_ADDRESS (val) + len; - - switch (format) - { - case 's': - next_address = VALUE_ADDRESS (val) - + value_print (value_addr (val), gdb_stdout, format, Val_pretty_default); - 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. */ - /* We often wrap here if there are long symbolic names. */ - wrap_here (" "); - next_address = VALUE_ADDRESS (val) - + print_insn (VALUE_ADDRESS (val), gdb_stdout); - break; - - default: - if (format == 0 - || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ARRAY - || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRING - || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRUCT - || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_UNION - || VALUE_REPEATED (val)) - value_print (val, gdb_stdout, format, Val_pretty_default); - else - print_scalar_formatted (VALUE_CONTENTS (val), VALUE_TYPE (val), - format, size, gdb_stdout); - } -} - -/* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR, - according to letters FORMAT and SIZE on STREAM. - FORMAT may not be zero. Formats s and i are not supported at this level. - - This is how the elements of an array or structure are printed - with a format. */ - -void -print_scalar_formatted (valaddr, type, format, size, stream) - char *valaddr; - struct type *type; - int format; - int size; - GDB_FILE *stream; -{ - LONGEST val_long; - int len = TYPE_LENGTH (type); - - if (len > sizeof (LONGEST) - && (format == 't' - || format == 'c' - || format == 'o' - || format == 'u' - || format == 'd' - || format == 'x')) - { - /* We can't print it normally, but we can print it in hex. - Printing it in the wrong radix is more useful than saying - "use /x, you dummy". */ - /* FIXME: we could also do octal or binary if that was the - 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); - return; - } - - if (format != 'f') - val_long = unpack_long (type, valaddr); - - /* If we are printing it as unsigned, truncate it in case it is actually - a negative signed value (e.g. "print/u (short)-1" should print 65535 - (if shorts are 16 bits) instead of 4294967295). */ - if (format != 'd') - { - if (len < sizeof (LONGEST)) - val_long &= ((LONGEST) 1 << HOST_CHAR_BIT * len) - 1; - } - - switch (format) - { - case 'x': - if (!size) - { - /* no size specified, like in print. Print varying # of digits. */ - print_longest (stream, 'x', 1, val_long); - } - else - switch (size) - { - case 'b': - case 'h': - case 'w': - case 'g': - print_longest (stream, size, 1, val_long); - break; - default: - error ("Undefined output size \"%c\".", size); - } - break; - - case 'd': - print_longest (stream, 'd', 1, val_long); - break; - - case 'u': - print_longest (stream, 'u', 0, val_long); - break; - - case 'o': - if (val_long) - print_longest (stream, 'o', 1, val_long); - else - fprintf_filtered (stream, "0"); - break; - - case 'a': - print_address (unpack_pointer (type, valaddr), stream); - break; - - case 'c': - value_print (value_from_longest (builtin_type_char, val_long), stream, 0, - Val_pretty_default); - break; - - case 'f': - if (len == sizeof (float)) - type = builtin_type_float; - else if (len == sizeof (double)) - type = builtin_type_double; - print_floating (valaddr, type, stream); - break; - - case 0: - abort (); - - case 't': - /* Binary; 't' stands for "two". */ - { - char bits[8*(sizeof val_long) + 1]; - char *cp = bits; - int width; - - if (!size) - width = 8*(sizeof val_long); - else - switch (size) - { - case 'b': - width = 8; - break; - case 'h': - width = 16; - break; - case 'w': - width = 32; - break; - case 'g': - width = 64; - break; - default: - error ("Undefined output size \"%c\".", size); - } - - bits[width] = '\0'; - while (width-- > 0) - { - bits[width] = (val_long & 1) ? '1' : '0'; - val_long >>= 1; - } - if (!size) - { - while (*cp && *cp == '0') - cp++; - if (*cp == '\0') - cp--; - } - fprintf_filtered (stream, local_binary_format_prefix()); - fprintf_filtered (stream, cp); - fprintf_filtered (stream, local_binary_format_suffix()); - } - break; - - default: - error ("Undefined output format \"%c\".", format); - } -} - -/* Specify default address for `x' command. - `info lines' uses this. */ - -void -set_next_address (addr) - CORE_ADDR addr; -{ - next_address = addr; - - /* Make address available to the user as $_. */ - set_internalvar (lookup_internalvar ("_"), - value_from_longest (lookup_pointer_type (builtin_type_void), - (LONGEST) addr)); -} - -/* Optionally print address ADDR symbolically as on STREAM, - after LEADIN. Print nothing if no symbolic name is found nearby. - Optionally also print source file and line number, if available. - DO_DEMANGLE controls whether to print a symbol in its native "raw" form, - or to interpret it as a possible C++ name and convert it back to source - form. However note that DO_DEMANGLE can be overridden by the specific - settings of the demangle and asm_demangle variables. */ - -void -print_address_symbolic (addr, stream, do_demangle, leadin) - CORE_ADDR addr; - GDB_FILE *stream; - int do_demangle; - char *leadin; -{ - struct minimal_symbol *msymbol; - struct symbol *symbol; - struct symtab *symtab = 0; - CORE_ADDR name_location = 0; - char *name = ""; - - /* First try to find the address in the symbol table, then - in the minsyms. Take the closest one. */ - - /* This is defective in the sense that it only finds text symbols. So - really this is kind of pointless--we should make sure that the - minimal symbols have everything we need (by changing that we could - 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)); - - if (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) - { - /* The msymbol is closer to the address than the symbol; - use the msymbol instead. */ - symbol = 0; - symtab = 0; - name_location = SYMBOL_VALUE_ADDRESS (msymbol); - if (do_demangle) - name = SYMBOL_SOURCE_NAME (msymbol); - else - name = SYMBOL_LINKAGE_NAME (msymbol); - } - } - if (symbol == NULL && msymbol == NULL) - return; - - /* 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 - CORE_ADDR. But when we detect unsigned wraparound in the - CORE_ADDR math, we ignore this test and print the offset, - because addr+max_symbolic_offset has wrapped through the end - of the address space back to the beginning, giving bogus comparison. */ - if (addr > name_location + max_symbolic_offset - && name_location + max_symbolic_offset > name_location) - return; - - fputs_filtered (leadin, stream); - fputs_filtered ("<", stream); - fputs_filtered (name, stream); - if (addr != name_location) - fprintf_filtered (stream, "+%u", (unsigned int)(addr - name_location)); - - /* Append source filename and line number if desired. Give specific - line # of this addr, if we have it; else line # of the nearest symbol. */ - if (print_symbol_filename) - { - struct symtab_and_line sal; - - sal = find_pc_line (addr, 0); - if (sal.symtab) - fprintf_filtered (stream, " at %s:%d", sal.symtab->filename, sal.line); - else if (symtab && symbol && symbol->line) - fprintf_filtered (stream, " at %s:%d", symtab->filename, symbol->line); - else if (symtab) - fprintf_filtered (stream, " in %s", symtab->filename); - } - fputs_filtered (">", stream); -} - -/* Print address ADDR on STREAM. USE_LOCAL means the same thing as for - print_longest. */ -void -print_address_numeric (addr, use_local, stream) - CORE_ADDR addr; - int use_local; - GDB_FILE *stream; -{ - /* This assumes a CORE_ADDR can fit in a LONGEST. Probably a safe - assumption. We pass use_local but I'm not completely sure whether - that is correct. When (if ever) should we *not* use_local? */ - print_longest (stream, 'x', 1, (unsigned LONGEST) addr); -} - -/* Print address ADDR symbolically on STREAM. - First print it as a number. Then perhaps print - after the number. */ - -void -print_address (addr, stream) - CORE_ADDR addr; - GDB_FILE *stream; -{ - print_address_numeric (addr, 1, stream); - print_address_symbolic (addr, stream, asm_demangle, " "); -} - -/* Print address ADDR symbolically on STREAM. Parameter DEMANGLE - controls whether to print the symbolic name "raw" or demangled. - Global setting "addressprint" controls whether to print hex address - or not. */ - -void -print_address_demangle (addr, stream, do_demangle) - CORE_ADDR addr; - GDB_FILE *stream; - int do_demangle; -{ - if (addr == 0) - { - fprintf_filtered (stream, "0"); - } - else if (addressprint) - { - print_address_numeric (addr, 1, stream); - print_address_symbolic (addr, stream, do_demangle, " "); - } - else - { - print_address_symbolic (addr, stream, do_demangle, ""); - } -} - - -/* These are the types that $__ will get after an examine command of one - of these sizes. */ - -static struct type *examine_b_type; -static struct type *examine_h_type; -static struct type *examine_w_type; -static struct type *examine_g_type; - -/* Examine data at address ADDR in format FMT. - Fetch it from memory and print on gdb_stdout. */ - -static void -do_examine (fmt, addr) - struct format_data fmt; - CORE_ADDR addr; -{ - register char format = 0; - register char size; - register int count = 1; - struct type *val_type = NULL; - register int i; - register int maxelts; - - format = fmt.format; - size = fmt.size; - count = fmt.count; - next_address = addr; - - /* String or instruction format implies fetch single bytes - regardless of the specified size. */ - if (format == 's' || format == 'i') - size = 'b'; - - if (size == 'b') - val_type = examine_b_type; - else if (size == 'h') - val_type = examine_h_type; - else if (size == 'w') - val_type = examine_w_type; - else if (size == 'g') - val_type = examine_g_type; - - maxelts = 8; - if (size == 'w') - maxelts = 4; - if (size == 'g') - maxelts = 2; - if (format == 's' || format == 'i') - maxelts = 1; - - /* Print as many objects as specified in COUNT, at most maxelts per line, - with the address of the next one at the start of each line. */ - - while (count > 0) - { - print_address (next_address, gdb_stdout); - printf_filtered (":"); - for (i = maxelts; - i > 0 && count > 0; - i--, count--) - { - printf_filtered ("\t"); - /* 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); - print_formatted (last_examine_value, format, size); - } - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - } -} - -static void -validate_format (fmt, cmdname) - struct format_data fmt; - char *cmdname; -{ - if (fmt.size != 0) - error ("Size letters are meaningless in \"%s\" command.", cmdname); - if (fmt.count != 1) - error ("Item count other than 1 is meaningless in \"%s\" command.", - cmdname); - if (fmt.format == 'i' || fmt.format == 's') - error ("Format letter \"%c\" is meaningless in \"%s\" command.", - fmt.format, cmdname); -} - -/* Evaluate string EXP as an expression in the current language and - print the resulting value. EXP may contain a format specifier as the - first argument ("/x myvar" for example, to print myvar in hex). - */ - -static void -print_command_1 (exp, inspect, voidprint) - char *exp; - int inspect; - int voidprint; -{ - struct expression *expr; - register struct cleanup *old_chain = 0; - register char format = 0; - register value_ptr val; - struct format_data fmt; - int cleanup = 0; - - /* Pass inspect flag to the rest of the print routines in a global (sigh). */ - inspect_it = inspect; - - if (exp && *exp == '/') - { - exp++; - fmt = decode_format (&exp, last_format, 0); - validate_format (fmt, "print"); - last_format = format = fmt.format; - } - else - { - fmt.count = 1; - fmt.format = 0; - fmt.size = 0; - } - - if (exp && *exp) - { - extern int objectprint; - struct type *type; - expr = parse_expression (exp); - old_chain = make_cleanup (free_current_contents, &expr); - cleanup = 1; - val = evaluate_expression (expr); - - /* C++: figure out what type we actually want to print it as. */ - type = VALUE_TYPE (val); - - if (objectprint - && ( TYPE_CODE (type) == TYPE_CODE_PTR - || TYPE_CODE (type) == TYPE_CODE_REF) - && ( TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT - || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_UNION)) - { - value_ptr v; - - v = value_from_vtable_info (val, TYPE_TARGET_TYPE (type)); - if (v != 0) - { - val = v; - type = VALUE_TYPE (val); - } - } - } - else - val = access_value_history (0); - - if (voidprint || (val && VALUE_TYPE (val) && - TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_VOID)) - { - int histindex = record_latest_value (val); - - if (histindex >= 0) - annotate_value_history_begin (histindex, VALUE_TYPE (val)); - else - annotate_value_begin (VALUE_TYPE (val)); - - if (inspect) - printf_unfiltered ("\031(gdb-makebuffer \"%s\" %d '(\"", exp, histindex); - else - if (histindex >= 0) printf_filtered ("$%d = ", histindex); - - if (histindex >= 0) - annotate_value_history_value (); - - print_formatted (val, format, fmt.size); - printf_filtered ("\n"); - - if (histindex >= 0) - annotate_value_history_end (); - else - annotate_value_end (); - - if (inspect) - printf_unfiltered("\") )\030"); - } - - if (cleanup) - do_cleanups (old_chain); - inspect_it = 0; /* Reset print routines to normal */ -} - -/* ARGSUSED */ -static void -print_command (exp, from_tty) - char *exp; - int from_tty; -{ - print_command_1 (exp, 0, 1); -} - -/* Same as print, except in epoch, it gets its own window */ -/* ARGSUSED */ -static void -inspect_command (exp, from_tty) - char *exp; - int from_tty; -{ - extern int epoch_interface; - - print_command_1 (exp, epoch_interface, 1); -} - -/* Same as print, except it doesn't print void results. */ -/* ARGSUSED */ -static void -call_command (exp, from_tty) - char *exp; - int from_tty; -{ - print_command_1 (exp, 0, 0); -} - -/* ARGSUSED */ -static void -output_command (exp, from_tty) - char *exp; - int from_tty; -{ - struct expression *expr; - register struct cleanup *old_chain; - register char format = 0; - register value_ptr val; - struct format_data fmt; - - if (exp && *exp == '/') - { - exp++; - fmt = decode_format (&exp, 0, 0); - validate_format (fmt, "output"); - format = fmt.format; - } - - expr = parse_expression (exp); - old_chain = make_cleanup (free_current_contents, &expr); - - val = evaluate_expression (expr); - - annotate_value_begin (VALUE_TYPE (val)); - - print_formatted (val, format, fmt.size); - - annotate_value_end (); - - do_cleanups (old_chain); -} - -/* ARGSUSED */ -static void -set_command (exp, from_tty) - char *exp; - int from_tty; -{ - struct expression *expr = parse_expression (exp); - register struct cleanup *old_chain - = make_cleanup (free_current_contents, &expr); - evaluate_expression (expr); - do_cleanups (old_chain); -} - -/* ARGSUSED */ -static void -address_info (exp, from_tty) - char *exp; - int from_tty; -{ - register struct symbol *sym; - register struct minimal_symbol *msymbol; - register long val; - register long basereg; - int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero - if exp is a field of `this'. */ - - if (exp == 0) - error ("Argument required."); - - sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE, - &is_a_field_of_this, (struct symtab **)NULL); - if (sym == NULL) - { - if (is_a_field_of_this) - { - printf_filtered ("Symbol \""); - fprintf_symbol_filtered (gdb_stdout, exp, - current_language->la_language, DMGL_ANSI); - printf_filtered ("\" is a field of the local class variable `this'\n"); - return; - } - - msymbol = lookup_minimal_symbol (exp, (struct objfile *) NULL); - - if (msymbol != NULL) - { - 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"); - } - else - error ("No symbol \"%s\" in current context.", exp); - return; - } - - printf_filtered ("Symbol \""); - fprintf_symbol_filtered (gdb_stdout, SYMBOL_NAME (sym), - current_language->la_language, DMGL_ANSI); - printf_filtered ("\" is ", SYMBOL_NAME (sym)); - val = SYMBOL_VALUE (sym); - basereg = SYMBOL_BASEREG (sym); - - switch (SYMBOL_CLASS (sym)) - { - case LOC_CONST: - case LOC_CONST_BYTES: - printf_filtered ("constant"); - break; - - case LOC_LABEL: - printf_filtered ("a label at address "); - print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout); - break; - - case LOC_REGISTER: - printf_filtered ("a variable in register %s", reg_names[val]); - break; - - case LOC_STATIC: - printf_filtered ("static storage at address "); - print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout); - break; - - case LOC_REGPARM: - printf_filtered ("an argument in register %s", reg_names[val]); - break; - - case LOC_REGPARM_ADDR: - printf_filtered ("address of an argument in register %s", reg_names[val]); - break; - - case LOC_ARG: - printf_filtered ("an argument at offset %ld", val); - break; - - case LOC_LOCAL_ARG: - printf_filtered ("an argument at frame offset %ld", val); - break; - - case LOC_LOCAL: - printf_filtered ("a local variable at frame offset %ld", val); - break; - - case LOC_REF_ARG: - printf_filtered ("a reference argument at offset %ld", val); - break; - - case LOC_BASEREG: - printf_filtered ("a variable at offset %ld from register %s", - val, reg_names[basereg]); - break; - - case LOC_BASEREG_ARG: - printf_filtered ("an argument at offset %ld from register %s", - val, reg_names[basereg]); - break; - - case LOC_TYPEDEF: - printf_filtered ("a typedef"); - 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_OPTIMIZED_OUT: - printf_filtered ("optimized out"); - break; - - default: - printf_filtered ("of unknown (botched) type"); - break; - } - printf_filtered (".\n"); -} - -static void -x_command (exp, from_tty) - char *exp; - int from_tty; -{ - struct expression *expr; - struct format_data fmt; - struct cleanup *old_chain; - struct value *val; - - fmt.format = last_format; - fmt.size = last_size; - fmt.count = 1; - - if (exp && *exp == '/') - { - exp++; - fmt = decode_format (&exp, last_format, last_size); - } - - /* If we have an expression, evaluate it and use it as the address. */ - - if (exp != 0 && *exp != 0) - { - expr = parse_expression (exp); - /* Cause expression not to be there any more - if this command is repeated with Newline. - But don't clobber a user-defined command's definition. */ - if (from_tty) - *exp = 0; - old_chain = make_cleanup (free_current_contents, &expr); - val = evaluate_expression (expr); - if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_REF) - val = value_ind (val); - /* In rvalue contexts, such as this, functions are coerced into - pointers to functions. This makes "x/i main" work. */ - if (/* last_format == 'i' - && */ TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC - && VALUE_LVAL (val) == lval_memory) - next_address = VALUE_ADDRESS (val); - else - next_address = value_as_pointer (val); - do_cleanups (old_chain); - } - - do_examine (fmt, next_address); - - /* If the examine succeeds, we remember its size and format for next time. */ - last_size = fmt.size; - last_format = fmt.format; - - /* Set a couple of internal variables if appropriate. */ - if (last_examine_value) - { - /* Make last address examined available to the user as $_. Use - the correct pointer type. */ - set_internalvar (lookup_internalvar ("_"), - value_from_longest ( - lookup_pointer_type (VALUE_TYPE (last_examine_value)), - (LONGEST) last_examine_address)); - - /* Make contents of last address examined available to the user as $__.*/ - set_internalvar (lookup_internalvar ("__"), last_examine_value); - } -} - - -/* Add an expression to the auto-display chain. - Specify the expression. */ - -static void -display_command (exp, from_tty) - char *exp; - int from_tty; -{ - struct format_data fmt; - register struct expression *expr; - register struct display *new; - - if (exp == 0) - { - do_displays (); - return; - } - - 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; - } - - innermost_block = 0; - expr = parse_expression (exp); - - new = (struct display *) xmalloc (sizeof (struct display)); - - new->exp = expr; - new->block = innermost_block; - new->next = display_chain; - new->number = ++display_number; - new->format = fmt; - new->status = enabled; - display_chain = new; - - if (from_tty && target_has_execution) - do_one_display (new); - - dont_repeat (); -} - -static void -free_display (d) - struct display *d; -{ - free ((PTR)d->exp); - free ((PTR)d); -} - -/* Clear out the display_chain. - Done when new symtabs are loaded, since this invalidates - the types stored in many expressions. */ - -void -clear_displays () -{ - register struct display *d; - - while ((d = display_chain) != NULL) - { - free ((PTR)d->exp); - display_chain = d->next; - free ((PTR)d); - } -} - -/* Delete the auto-display number NUM. */ - -static void -delete_display (num) - int num; -{ - register struct display *d1, *d; - - if (!display_chain) - error ("No display number %d.", num); - - if (display_chain->number == num) - { - d1 = display_chain; - display_chain = d1->next; - free_display (d1); - } - else - for (d = display_chain; ; d = d->next) - { - if (d->next == 0) - error ("No display number %d.", num); - if (d->next->number == num) - { - d1 = d->next; - d->next = d1->next; - free_display (d1); - break; - } - } -} - -/* Delete some values from the auto-display chain. - Specify the element numbers. */ - -static void -undisplay_command (args, from_tty) - char *args; - int from_tty; -{ - register char *p = args; - register char *p1; - register int num; - - if (args == 0) - { - if (query ("Delete all auto-display expressions? ")) - clear_displays (); - dont_repeat (); - return; - } - - while (*p) - { - p1 = p; - while (*p1 >= '0' && *p1 <= '9') p1++; - if (*p1 && *p1 != ' ' && *p1 != '\t') - error ("Arguments must be display numbers."); - - num = atoi (p); - - delete_display (num); - - p = p1; - while (*p == ' ' || *p == '\t') p++; - } - dont_repeat (); -} - -/* Display a single auto-display. - Do nothing if the display cannot be printed in the current context, - or if the display is disabled. */ - -static void -do_one_display (d) - struct display *d; -{ - int within_current_scope; - - if (d->status == disabled) - return; - - if (d->block) - within_current_scope = contained_in (get_selected_block (), d->block); - else - within_current_scope = 1; - if (!within_current_scope) - return; - - current_display_number = d->number; - - annotate_display_begin (); - printf_filtered ("%d", d->number); - annotate_display_number_end (); - printf_filtered (": "); - if (d->format.size) - { - CORE_ADDR addr; - - annotate_display_format (); - - printf_filtered ("x/"); - if (d->format.count != 1) - printf_filtered ("%d", d->format.count); - printf_filtered ("%c", d->format.format); - if (d->format.format != 'i' && d->format.format != 's') - printf_filtered ("%c", d->format.size); - printf_filtered (" "); - - annotate_display_expression (); - - print_expression (d->exp, gdb_stdout); - annotate_display_expression_end (); - - if (d->format.count != 1) - printf_filtered ("\n"); - else - printf_filtered (" "); - - addr = value_as_pointer (evaluate_expression (d->exp)); - if (d->format.format == 'i') - addr = ADDR_BITS_REMOVE (addr); - - annotate_display_value (); - - do_examine (d->format, addr); - } - else - { - annotate_display_format (); - - if (d->format.format) - printf_filtered ("/%c ", d->format.format); - - annotate_display_expression (); - - print_expression (d->exp, gdb_stdout); - annotate_display_expression_end (); - - printf_filtered (" = "); - - annotate_display_expression (); - - print_formatted (evaluate_expression (d->exp), - d->format.format, d->format.size); - printf_filtered ("\n"); - } - - annotate_display_end (); - - gdb_flush (gdb_stdout); - current_display_number = -1; -} - -/* Display all of the values on the auto-display chain which can be - evaluated in the current scope. */ - -void -do_displays () -{ - register struct display *d; - - for (d = display_chain; d; d = d->next) - do_one_display (d); -} - -/* Delete the auto-display which we were in the process of displaying. - This is done when there is an error or a signal. */ - -void -disable_display (num) - int num; -{ - register struct display *d; - - for (d = display_chain; d; d = d->next) - if (d->number == num) - { - d->status = disabled; - return; - } - printf_unfiltered ("No display number %d.\n", num); -} - -void -disable_current_display () -{ - if (current_display_number >= 0) - { - disable_display (current_display_number); - fprintf_unfiltered (gdb_stderr, "Disabling display %d to avoid infinite recursion.\n", - current_display_number); - } - current_display_number = -1; -} - -static void -display_info (ignore, from_tty) - char *ignore; - int from_tty; -{ - register struct display *d; - - if (!display_chain) - printf_unfiltered ("There are no auto-display expressions now.\n"); - else - printf_filtered ("Auto-display expressions now in effect:\n\ -Num Enb Expression\n"); - - for (d = display_chain; d; d = d->next) - { - printf_filtered ("%d: %c ", d->number, "ny"[(int)d->status]); - if (d->format.size) - printf_filtered ("/%d%c%c ", d->format.count, d->format.size, - d->format.format); - else if (d->format.format) - printf_filtered ("/%c ", d->format.format); - print_expression (d->exp, gdb_stdout); - if (d->block && !contained_in (get_selected_block (), d->block)) - printf_filtered (" (cannot be evaluated in the current context)"); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - } -} - -static void -enable_display (args, from_tty) - char *args; - int from_tty; -{ - register char *p = args; - register char *p1; - register int num; - register struct display *d; - - if (p == 0) - { - for (d = display_chain; d; d = d->next) - d->status = enabled; - } - else - while (*p) - { - p1 = p; - while (*p1 >= '0' && *p1 <= '9') - p1++; - if (*p1 && *p1 != ' ' && *p1 != '\t') - error ("Arguments must be display numbers."); - - num = atoi (p); - - for (d = display_chain; d; d = d->next) - if (d->number == num) - { - d->status = enabled; - goto win; - } - printf_unfiltered ("No display number %d.\n", num); - win: - p = p1; - while (*p == ' ' || *p == '\t') - p++; - } -} - -/* ARGSUSED */ -static void -disable_display_command (args, from_tty) - char *args; - int from_tty; -{ - register char *p = args; - register char *p1; - register struct display *d; - - if (p == 0) - { - for (d = display_chain; d; d = d->next) - d->status = disabled; - } - else - while (*p) - { - p1 = p; - while (*p1 >= '0' && *p1 <= '9') - p1++; - if (*p1 && *p1 != ' ' && *p1 != '\t') - error ("Arguments must be display numbers."); - - disable_display (atoi (p)); - - p = p1; - while (*p == ' ' || *p == '\t') - p++; - } -} - - -/* Print the value in stack frame FRAME of a variable - specified by a struct symbol. */ - -void -print_variable_value (var, frame, stream) - struct symbol *var; - FRAME frame; - GDB_FILE *stream; -{ - value_ptr val = read_var_value (var, frame); - value_print (val, stream, 0, Val_pretty_default); -} - -/* Print the arguments of a stack frame, given the function FUNC - running in that frame (as a symbol), the info on the frame, - and the number of args according to the stack frame (or -1 if unknown). */ - -/* References here and elsewhere to "number of args according to the - stack frame" appear in all cases to refer to "number of ints of args - according to the stack frame". At least for VAX, i386, isi. */ - -void -print_frame_args (func, fi, num, stream) - struct symbol *func; - struct frame_info *fi; - int num; - GDB_FILE *stream; -{ - struct block *b = NULL; - int nsyms = 0; - int first = 1; - register int i; - register struct symbol *sym; - register value_ptr val; - /* Offset of next stack argument beyond the one we have seen that is - at the highest offset. - -1 if we haven't come to a stack argument yet. */ - long highest_offset = -1; - int arg_size; - /* Number of ints of arguments that we have printed so far. */ - int args_printed = 0; - - if (func) - { - b = SYMBOL_BLOCK_VALUE (func); - nsyms = BLOCK_NSYMS (b); - } - - for (i = 0; i < nsyms; i++) - { - QUIT; - sym = BLOCK_SYM (b, i); - - /* Keep track of the highest stack argument offset seen, and - skip over any kinds of symbols we don't care about. */ - - switch (SYMBOL_CLASS (sym)) { - case LOC_ARG: - case LOC_REF_ARG: - { - long current_offset = SYMBOL_VALUE (sym); - - arg_size = TYPE_LENGTH (SYMBOL_TYPE (sym)); - - /* Compute address of next argument by adding the size of - this argument and rounding to an int boundary. */ - current_offset - = ((current_offset + arg_size + sizeof (int) - 1) - & ~(sizeof (int) - 1)); - - /* If this is the highest offset seen yet, set highest_offset. */ - if (highest_offset == -1 - || (current_offset > highest_offset)) - highest_offset = current_offset; - - /* Add the number of ints we're about to print to args_printed. */ - args_printed += (arg_size + sizeof (int) - 1) / sizeof (int); - } - - /* We care about types of symbols, but don't need to keep track of - stack offsets in them. */ - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_LOCAL_ARG: - case LOC_BASEREG_ARG: - break; - - /* Other types of symbols we just skip over. */ - default: - continue; - } - - /* We have to look up the symbol because arguments can have - two entries (one a parameter, one a local) and the one we - want is the local, which lookup_symbol will find for us. - This includes gcc1 (not gcc2) on the sparc when passing a - small structure and gcc2 when the argument type is float - and it is passed as a double and converted to float by - the prologue (in the latter case the type of the LOC_ARG - symbol is double and the type of the LOC_LOCAL symbol is - float). */ - /* But if the parameter name is null, don't try it. - Null parameter names occur on the RS/6000, for traceback tables. - FIXME, should we even print them? */ - - if (*SYMBOL_NAME (sym)) - { - struct symbol *nsym; - nsym = lookup_symbol - (SYMBOL_NAME (sym), - b, VAR_NAMESPACE, (int *)NULL, (struct symtab **)NULL); - if (SYMBOL_CLASS (nsym) == LOC_REGISTER) - { - /* There is a LOC_ARG/LOC_REGISTER pair. This means that - it was passed on the stack and loaded into a register, - or passed in a register and stored in a stack slot. - GDB 3.x used the LOC_ARG; GDB 4.0-4.11 used the LOC_REGISTER. - - Reasons for using the LOC_ARG: - (1) because find_saved_registers may be slow for remote - debugging, - (2) because registers are often re-used and stack slots - rarely (never?) are. Therefore using the stack slot is - much less likely to print garbage. - - Reasons why we might want to use the LOC_REGISTER: - (1) So that the backtrace prints the same value as - "print foo". I see no compelling reason why this needs - to be the case; having the backtrace print the value which - was passed in, and "print foo" print the value as modified - within the called function, makes perfect sense to me. - - Additional note: It might be nice if "info args" displayed - both values. - One more note: There is a case with sparc structure passing - where we need to use the LOC_REGISTER, but this is dealt with - by creating a single LOC_REGPARM in symbol reading. */ - - /* Leave sym (the LOC_ARG) alone. */ - ; - } - else - sym = nsym; - } - - /* Print the current arg. */ - if (! first) - fprintf_filtered (stream, ", "); - wrap_here (" "); - - annotate_arg_begin (); - - fprintf_symbol_filtered (stream, SYMBOL_SOURCE_NAME (sym), - SYMBOL_LANGUAGE (sym), DMGL_PARAMS | DMGL_ANSI); - annotate_arg_name_end (); - fputs_filtered ("=", stream); - - /* Avoid value_print because it will deref ref parameters. We just - want to print their addresses. Print ??? for args whose address - we do not know. We pass 2 as "recurse" to val_print because our - standard indentation here is 4 spaces, and val_print indents - 2 for each recurse. */ - val = read_var_value (sym, FRAME_INFO_ID (fi)); - - 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); - else - fputs_filtered ("???", stream); - - annotate_arg_end (); - - first = 0; - } - - /* Don't print nameless args in situations where we don't know - enough about the stack to find them. */ - if (num != -1) - { - long start; - - if (highest_offset == -1) - start = FRAME_ARGS_SKIP; - else - start = highest_offset; - - print_frame_nameless_args (fi, start, num - args_printed, - first, stream); - } -} - -/* Print nameless args on STREAM. - FI is the frameinfo for this frame, START is the offset - of the first nameless arg, and NUM is the number of nameless args to - print. FIRST is nonzero if this is the first argument (not just - the first nameless arg). */ -static void -print_frame_nameless_args (fi, start, num, first, stream) - struct frame_info *fi; - long start; - int num; - int first; - GDB_FILE *stream; -{ - int i; - CORE_ADDR argsaddr; - long arg_value; - - for (i = 0; i < num; i++) - { - QUIT; -#ifdef NAMELESS_ARG_VALUE - NAMELESS_ARG_VALUE (fi, start, &arg_value); -#else - argsaddr = FRAME_ARGS_ADDRESS (fi); - if (!argsaddr) - return; - - arg_value = read_memory_integer (argsaddr + start, sizeof (int)); -#endif - - if (!first) - fprintf_filtered (stream, ", "); - -#ifdef PRINT_NAMELESS_INTEGER - PRINT_NAMELESS_INTEGER (stream, arg_value); -#else -#ifdef PRINT_TYPELESS_INTEGER - PRINT_TYPELESS_INTEGER (stream, builtin_type_int, (LONGEST) arg_value); -#else - fprintf_filtered (stream, "%d", arg_value); -#endif /* PRINT_TYPELESS_INTEGER */ -#endif /* PRINT_NAMELESS_INTEGER */ - first = 0; - start += sizeof (int); - } -} - -/* ARGSUSED */ -static void -printf_command (arg, from_tty) - char *arg; - int from_tty; -{ - register char *f; - register char *s = arg; - char *string; - value_ptr *val_args; - char *substrings; - char *current_substring; - int nargs = 0; - int allocated_args = 20; - struct cleanup *old_cleanups; - - val_args = (value_ptr *) xmalloc (allocated_args * sizeof (value_ptr)); - old_cleanups = make_cleanup (free_current_contents, &val_args); - - if (s == 0) - error_no_arg ("format-control string and values to print"); - - /* Skip white space before format string */ - while (*s == ' ' || *s == '\t') s++; - - /* A format string should follow, enveloped in double quotes */ - if (*s++ != '"') - error ("Bad format string, missing '\"'."); - - /* Parse the format-control string and copy it into the string STRING, - processing some kinds of escape sequence. */ - - f = string = (char *) alloca (strlen (s) + 1); - - while (*s != '"') - { - int c = *s++; - switch (c) - { - case '\0': - error ("Bad format string, non-terminated '\"'."); - - case '\\': - switch (c = *s++) - { - case '\\': - *f++ = '\\'; - break; - case 'a': -#ifdef __STDC__ - *f++ = '\a'; -#else - *f++ = '\007'; /* Bell */ -#endif - break; - case 'b': - *f++ = '\b'; - break; - case 'f': - *f++ = '\f'; - break; - case 'n': - *f++ = '\n'; - break; - case 'r': - *f++ = '\r'; - break; - case 't': - *f++ = '\t'; - break; - case 'v': - *f++ = '\v'; - break; - case '"': - *f++ = '"'; - break; - default: - /* ??? TODO: handle other escape sequences */ - error ("Unrecognized escape character \\%c in format string.", - c); - } - break; - - default: - *f++ = c; - } - } - - /* Skip over " and following space and comma. */ - s++; - *f++ = '\0'; - while (*s == ' ' || *s == '\t') s++; - - if (*s != ',' && *s != 0) - error ("Invalid argument syntax"); - - if (*s == ',') s++; - while (*s == ' ' || *s == '\t') s++; - - /* Need extra space for the '\0's. Doubling the size is sufficient. */ - substrings = alloca (strlen (string) * 2); - current_substring = substrings; - - { - /* Now scan the string for %-specs and see what kinds of args they want. - argclass[I] classifies the %-specs so we can give printf_filtered - something of the right size. */ - - enum argclass {no_arg, int_arg, string_arg, double_arg, long_long_arg}; - enum argclass *argclass; - enum argclass this_argclass; - char *last_arg; - int nargs_wanted; - int lcount; - int i; - - argclass = (enum argclass *) alloca (strlen (s) * sizeof *argclass); - nargs_wanted = 0; - f = string; - last_arg = string; - while (*f) - if (*f++ == '%') - { - lcount = 0; - while (strchr ("0123456789.hlL-+ #", *f)) - { - if (*f == 'l' || *f == 'L') - lcount++; - f++; - } - switch (*f) - { - case 's': - this_argclass = string_arg; - break; - - case 'e': - case 'f': - case 'g': - this_argclass = double_arg; - break; - - case '*': - error ("`*' not supported for precision or width in printf"); - - case 'n': - error ("Format specifier `n' not supported in printf"); - - case '%': - this_argclass = no_arg; - break; - - default: - if (lcount > 1) - this_argclass = long_long_arg; - else - this_argclass = int_arg; - break; - } - f++; - if (this_argclass != no_arg) - { - strncpy (current_substring, last_arg, f - last_arg); - current_substring += f - last_arg; - *current_substring++ = '\0'; - last_arg = f; - argclass[nargs_wanted++] = this_argclass; - } - } - - /* Now, parse all arguments and evaluate them. - Store the VALUEs in VAL_ARGS. */ - - while (*s != '\0') - { - char *s1; - if (nargs == allocated_args) - val_args = (value_ptr *) xrealloc ((char *) val_args, - (allocated_args *= 2) - * sizeof (value_ptr)); - s1 = s; - val_args[nargs] = parse_to_comma_and_eval (&s1); - - /* If format string wants a float, unchecked-convert the value to - floating point of the same size */ - - if (argclass[nargs] == double_arg) - { - if (TYPE_LENGTH (VALUE_TYPE (val_args[nargs])) == sizeof (float)) - VALUE_TYPE (val_args[nargs]) = builtin_type_float; - if (TYPE_LENGTH (VALUE_TYPE (val_args[nargs])) == sizeof (double)) - VALUE_TYPE (val_args[nargs]) = builtin_type_double; - } - nargs++; - s = s1; - if (*s == ',') - s++; - } - - if (nargs != nargs_wanted) - error ("Wrong number of arguments for specified format-string"); - - /* Now actually print them. */ - current_substring = substrings; - for (i = 0; i < nargs; i++) - { - switch (argclass[i]) - { - case string_arg: - { - char *str; - CORE_ADDR tem; - int j; - tem = value_as_pointer (val_args[i]); - - /* This is a %s argument. Find the length of the string. */ - for (j = 0; ; j++) - { - char c; - QUIT; - read_memory (tem + j, &c, 1); - if (c == 0) - break; - } - - /* Copy the string contents into a string inside GDB. */ - str = (char *) alloca (j + 1); - read_memory (tem, str, j); - str[j] = 0; - - printf_filtered (current_substring, str); - } - break; - case double_arg: - { - double val = value_as_double (val_args[i]); - printf_filtered (current_substring, val); - break; - } - case long_long_arg: -#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG) - { - long long val = value_as_long (val_args[i]); - printf_filtered (current_substring, val); - break; - } -#else - error ("long long not supported in printf"); -#endif - case int_arg: - { - /* FIXME: there should be separate int_arg and long_arg. */ - long val = value_as_long (val_args[i]); - printf_filtered (current_substring, val); - break; - } - default: - error ("internal error in printf_command"); - } - /* Skip to the next substring. */ - current_substring += strlen (current_substring) + 1; - } - /* Print the portion of the format string after the last argument. */ - printf_filtered (last_arg); - } - do_cleanups (old_cleanups); -} - -/* Dump a specified section of assembly code. With no command line - arguments, this command will dump the assembly code for the - function surrounding the pc value in the selected frame. With one - argument, it will dump the assembly code surrounding that pc value. - Two arguments are interpeted as bounds within which to dump - assembly. */ - -/* ARGSUSED */ -static void -disassemble_command (arg, from_tty) - char *arg; - int from_tty; -{ - CORE_ADDR low, high; - char *name; - CORE_ADDR pc; - char *space_index; - - name = NULL; - if (!arg) - { - if (!selected_frame) - error ("No frame selected.\n"); - - 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"); - } - else if (!(space_index = (char *) strchr (arg, ' '))) - { - /* One argument. */ - pc = parse_and_eval_address (arg); - if (find_pc_partial_function (pc, &name, &low, &high) == 0) - error ("No function contains specified address.\n"); - } - else - { - /* Two arguments. */ - *space_index = '\0'; - low = parse_and_eval_address (arg); - high = parse_and_eval_address (space_index + 1); - } - - 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. */ - 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); -} - - -void -_initialize_printcmd () -{ - current_display_number = -1; - - add_info ("address", address_info, - "Describe where variable VAR is stored."); - - add_com ("x", class_vars, x_command, - "Examine memory: x/FMT ADDRESS.\n\ -ADDRESS is an expression for the memory address to examine.\n\ -FMT is a repeat count followed by a format letter and a size letter.\n\ -Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\ - t(binary), f(float), a(address), i(instruction), c(char) and s(string).\n\ -Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\ -The specified number of objects of the specified size are printed\n\ -according to the format.\n\n\ -Defaults for format and size letters are those previously used.\n\ -Default count is 1. Default address is following last thing printed\n\ -with this command or \"print\"."); - - add_com ("disassemble", class_vars, disassemble_command, - "Disassemble a specified section of memory.\n\ -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 0 - add_com ("whereis", class_vars, whereis_command, - "Print line number and file of definition of variable."); -#endif - - add_info ("display", display_info, - "Expressions to display when program stops, with code numbers."); - - add_cmd ("undisplay", class_vars, undisplay_command, - "Cancel some expressions to be displayed when program stops.\n\ -Arguments are the code numbers of the expressions to stop displaying.\n\ -No argument means cancel all automatic-display expressions.\n\ -\"delete display\" has the same effect as this command.\n\ -Do \"info display\" to see current list of code numbers.", - &cmdlist); - - add_com ("display", class_vars, display_command, - "Print value of expression EXP each time the program stops.\n\ -/FMT may be used before EXP as in the \"print\" command.\n\ -/FMT \"i\" or \"s\" or including a size-letter is allowed,\n\ -as in the \"x\" command, and then EXP is used to get the address to examine\n\ -and examining is done as in the \"x\" command.\n\n\ -With no argument, display all currently requested auto-display expressions.\n\ -Use \"undisplay\" to cancel display requests previously made."); - - add_cmd ("display", class_vars, enable_display, - "Enable some expressions to be displayed when program stops.\n\ -Arguments are the code numbers of the expressions to resume displaying.\n\ -No argument means enable all automatic-display expressions.\n\ -Do \"info display\" to see current list of code numbers.", &enablelist); - - add_cmd ("display", class_vars, disable_display_command, - "Disable some expressions to be displayed when program stops.\n\ -Arguments are the code numbers of the expressions to stop displaying.\n\ -No argument means disable all automatic-display expressions.\n\ -Do \"info display\" to see current list of code numbers.", &disablelist); - - add_cmd ("display", class_vars, undisplay_command, - "Cancel some expressions to be displayed when program stops.\n\ -Arguments are the code numbers of the expressions to stop displaying.\n\ -No argument means cancel all automatic-display expressions.\n\ -Do \"info display\" to see current list of code numbers.", &deletelist); - - add_com ("printf", class_vars, printf_command, - "printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\ -This is useful for formatted output in user-defined commands."); - add_com ("output", class_vars, output_command, - "Like \"print\" but don't put in value history and don't print newline.\n\ -This is useful in user-defined commands."); - - add_prefix_cmd ("set", class_vars, set_command, -"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.", - &setlist, "set ", 1, &cmdlist); - - /* "call" is the same as "set", but handy for dbx users to call fns. */ - add_com ("call", class_vars, call_command, - "Call a function in the program.\n\ -The argument is the function name and arguments, in the notation of the\n\ -current working language. The result is printed and saved in the value\n\ -history, if it is not void."); - - add_cmd ("variable", class_vars, set_command, -"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\ -This may usually be abbreviated to simply \"set\".", - &setlist); - - add_com ("print", class_vars, print_command, - concat ("Print value of expression EXP.\n\ -Variables accessible are those of the lexical environment of the selected\n\ -stack frame, plus all those whose scope is global or an entire file.\n\ -\n\ -$NUM gets previous value number NUM. $ and $$ are the last two values.\n\ -$$NUM refers to NUM'th value back from the last one.\n\ -Names starting with $ refer to registers (with the values they would have\n\ -if the program were to return to the stack frame now selected, restoring\n\ -all registers saved by frames farther in) or else to debugger\n\ -\"convenience\" variables (any such name not a known register).\n\ -Use assignment expressions to give values to convenience variables.\n", - "\n\ -{TYPE}ADREXP refers to a datum of data type TYPE, located at address ADREXP.\n\ -@ is a binary operator for treating consecutive data objects\n\ -anywhere in memory as an array. FOO@NUM gives an array whose first\n\ -element is FOO, whose second element is stored in the space following\n\ -where FOO is stored, etc. FOO must be an expression whose value\n\ -resides in memory.\n", - "\n\ -EXP may be preceded with /FMT, where FMT is a format letter\n\ -but no count or size letter (see \"x\" command).", NULL)); - add_com_alias ("p", "print", class_vars, 1); - - add_com ("inspect", class_vars, inspect_command, -"Same as \"print\" command, except that if you are running in the epoch\n\ -environment, the value is printed in its own window."); - - add_show_from_set ( - add_set_cmd ("max-symbolic-offset", no_class, var_uinteger, - (char *)&max_symbolic_offset, - "Set the largest offset that will be printed in form.", - &setprintlist), - &showprintlist); - add_show_from_set ( - add_set_cmd ("symbol-filename", no_class, var_boolean, - (char *)&print_symbol_filename, - "Set printing of source filename and line number with .", - &setprintlist), - &showprintlist); - - examine_b_type = init_type (TYPE_CODE_INT, 1, 0, NULL, NULL); - examine_h_type = init_type (TYPE_CODE_INT, 2, 0, NULL, NULL); - examine_w_type = init_type (TYPE_CODE_INT, 4, 0, NULL, NULL); - examine_g_type = init_type (TYPE_CODE_INT, 8, 0, NULL, NULL); -} diff --git a/gnu/usr.bin/gdb/gdb/remote-utils.c b/gnu/usr.bin/gdb/gdb/remote-utils.c deleted file mode 100644 index 3f38d3e..0000000 --- a/gnu/usr.bin/gdb/gdb/remote-utils.c +++ /dev/null @@ -1,704 +0,0 @@ -/* Generic support for remote debugging interfaces. - - Copyright 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. */ - -/* This file actually contains two distinct logical "packages". They - are packaged together in this one file because they are typically - used together. - - The first package is an addition to the serial package. The - addition provides reading and writing with debugging output and - timeouts based on user settable variables. These routines are - intended to support serial port based remote backends. These - functions are prefixed with sr_. - - The second package is a collection of more or less generic - functions for use by remote backends. They support user settable - variables for debugging, retries, and the like. - - Todo: - - * a pass through mode a la kermit or telnet. - * autobaud. - * ask remote to change his baud rate. - */ - -#include - -#include "defs.h" -#include -#include "gdbcmd.h" -#include "target.h" -#include "serial.h" -#include "gdbcore.h" /* for exec_bfd */ -#include "inferior.h" /* for generic_mourn_inferior */ -#include "remote-utils.h" - -struct _sr_settings sr_settings = { - 4, /* timeout: - remote-hms.c had 2 - remote-bug.c had "with a timeout of 2, we time out waiting for - the prompt after an s-record dump." - - remote.c had (2): 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. -*/ - - 10, /* retries */ - NULL, /* device */ - NULL, /* descriptor */ -}; - -struct gr_settings *gr_settings = NULL; - -static void -usage(proto, junk) - char *proto; - char *junk; -{ - if (junk != NULL) - fprintf_unfiltered(gdb_stderr, "Unrecognized arguments: `%s'.\n", junk); - - error ("Usage: target %s [DEVICE [SPEED [DEBUG]]]\n\ -where DEVICE is the name of a device or HOST:PORT", proto, proto); - - return; -} - -#define CHECKDONE(p, q) \ -{ \ - if (q == p) \ - { \ - if (*p == '\0') \ - return; \ - else \ - usage(proto, p); \ - } \ -} - -void -sr_scan_args(proto, args) - char *proto; - char *args; -{ - int n; - char *p, *q; - - extern int strtol(); - - /* if no args, then nothing to do. */ - if (args == NULL || *args == '\0') - return; - - /* scan off white space. */ - for (p = args; isspace(*p); ++p) ;; - - /* find end of device name. */ - for (q = p; *q != '\0' && !isspace(*q); ++q) ;; - - /* check for missing or empty device name. */ - CHECKDONE(p, q); - sr_set_device(savestring(p, q - p)); - - /* look for baud rate. */ - n = strtol(q, &p, 10); - - /* check for missing or empty baud rate. */ - CHECKDONE(p, q); - baud_rate = n; - - /* look for debug value. */ - n = strtol(p, &q, 10); - - /* check for missing or empty debug value. */ - CHECKDONE(p, q); - sr_set_debug(n); - - /* scan off remaining white space. */ - for (p = q; isspace(*p); ++p) ;; - - /* if not end of string, then there's unrecognized junk. */ - if (*p != '\0') - usage(proto, p); - - return; -} - -void -gr_generic_checkin() -{ - sr_write_cr(""); - gr_expect_prompt(); -} - -void -gr_open(args, from_tty, gr) - char *args; - int from_tty; - struct gr_settings *gr; -{ - target_preopen(from_tty); - sr_scan_args(gr->ops->to_shortname, args); - unpush_target(gr->ops); - - gr_settings = gr; - - gr_set_dcache(dcache_init(gr->readfunc, gr->writefunc)); - - if (sr_get_desc() != NULL) - gr_close (0); - - /* If no args are specified, then we use the device specified by a - previous command or "set remotedevice". But if there is no - device, better stop now, not dump core. */ - - if (sr_get_device () == NULL) - usage (gr->ops->to_shortname, NULL); - - sr_set_desc(SERIAL_OPEN (sr_get_device())); - if (!sr_get_desc()) - perror_with_name((char *) sr_get_device()); - - if (baud_rate != -1) - { - if (SERIAL_SETBAUDRATE(sr_get_desc(), baud_rate) != 0) - { - SERIAL_CLOSE(sr_get_desc()); - perror_with_name(sr_get_device()); - } - } - - SERIAL_RAW (sr_get_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 (sr_get_desc ()); - - /* default retries */ - if (sr_get_retries() == 0) - sr_set_retries(1); - - /* default clear breakpoint function */ - if (gr_settings->clear_all_breakpoints == NULL) - gr_settings->clear_all_breakpoints = remove_breakpoints; - - if (from_tty) - { - printf_filtered ("Remote debugging using `%s'", sr_get_device ()); - if (baud_rate != -1) - printf_filtered (" at baud rate of %d", - baud_rate); - printf_filtered ("\n"); - } - - push_target(gr->ops); - gr_checkin(); - gr_clear_all_breakpoints (); - return; -} - -/* Read a character from the remote system masking it down to 7 bits - and doing all the fancy timeout stuff. */ - -int -sr_readchar () -{ - int buf; - - buf = SERIAL_READCHAR (sr_get_desc(), sr_get_timeout()); - - if (buf == SERIAL_TIMEOUT) - error ("Timeout reading from remote system."); - - if (sr_get_debug() > 0) - printf_unfiltered ("%c", buf); - - return buf & 0x7f; -} - -int -sr_pollchar() -{ - int buf; - - buf = SERIAL_READCHAR (sr_get_desc(), 0); - if (buf == SERIAL_TIMEOUT) - buf = 0; - if (sr_get_debug() > 0) - if (buf) - printf_unfiltered ("%c", buf); - else - printf_unfiltered (""); - - return buf & 0x7f; -} - -/* Keep discarding input from the remote system, until STRING is found. - Let the user break out immediately. */ -void -sr_expect (string) - char *string; -{ - char *p = string; - - immediate_quit = 1; - while (1) - { - if (sr_readchar () == *p) - { - p++; - if (*p == '\0') - { - immediate_quit = 0; - return; - } - } - else - p = string; - } -} - -void -sr_write (a, l) - char *a; - int l; -{ - int i; - - if (SERIAL_WRITE (sr_get_desc(), a, l) != 0) - perror_with_name ("sr_write: Error writing to remote"); - - if (sr_get_debug() > 0) - for (i = 0; i < l; i++) - printf_unfiltered ("%c", a[i]); - - return; -} - -void -sr_write_cr (s) - char *s; -{ - sr_write (s, strlen (s)); - sr_write ("\r", 1); - return; -} - -int -sr_timed_read (buf, n) - char *buf; - int n; -{ - int i; - char c; - - i = 0; - while (i < n) - { - c = sr_readchar (); - - if (c == 0) - return i; - buf[i] = c; - i++; - - } - return i; -} - -/* Get a hex digit from the remote system & return its value. If - ignore_space is nonzero, ignore spaces (not newline, tab, etc). */ - -int -sr_get_hex_digit (ignore_space) - int ignore_space; -{ - int ch; - - while (1) - { - ch = sr_readchar (); - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - else if (ch != ' ' || !ignore_space) - { - gr_expect_prompt (); - error ("Invalid hex digit from remote system."); - } - } -} - -/* Get a byte from the remote and put it in *BYT. Accept any number - leading spaces. */ -void -sr_get_hex_byte (byt) - char *byt; -{ - int val; - - val = sr_get_hex_digit (1) << 4; - val |= sr_get_hex_digit (0); - *byt = val; -} - -/* Read a 32-bit hex word from the remote, preceded by a space */ -long -sr_get_hex_word () -{ - long val; - int j; - - val = 0; - for (j = 0; j < 8; j++) - val = (val << 4) + sr_get_hex_digit (j == 0); - return val; -} - -/* Put a command string, in args, out to the remote. The remote is assumed to - be in raw mode, all writing/reading done through desc. - Ouput from the remote is placed on the users terminal until the - prompt from the remote is seen. - FIXME: Can't handle commands that take input. */ - -void -sr_com (args, fromtty) - char *args; - int fromtty; -{ - sr_check_open (); - - if (!args) - return; - - /* Clear all input so only command relative output is displayed */ - - sr_write_cr (args); - sr_write ("\030", 1); - gr_expect_prompt (); -} - -void -gr_close(quitting) - int quitting; -{ - gr_clear_all_breakpoints(); - - if (sr_is_open()) - { - SERIAL_CLOSE (sr_get_desc()); - sr_set_desc(NULL); - } - - return; -} - -/* gr_detach() - takes a program previously attached to and detaches it. - We better not have left any breakpoints - in the program or it'll die when it hits one. - Close the open connection to the remote debugger. - Use this when you want to detach and do something else - with your gdb. */ - -void -gr_detach(args, from_tty) - char *args; - int from_tty; -{ - if (args) - error ("Argument given to \"detach\" when remotely debugging."); - - if (sr_is_open()) - gr_clear_all_breakpoints (); - - pop_target (); - if (from_tty) - puts_filtered ("Ending remote debugging.\n"); - - return; -} - -void -gr_files_info (ops) - struct target_ops *ops; -{ -#ifdef __GO32__ - printf_filtered ("\tAttached to DOS asynctsr\n"); -#else - printf_filtered ("\tAttached to %s", sr_get_device()); - if (baud_rate != -1) - printf_filtered ("at %d baud", baud_rate); - printf_filtered ("\n"); -#endif - - if (exec_bfd) - { - printf_filtered ("\tand running program %s\n", - bfd_get_filename (exec_bfd)); - } - printf_filtered ("\tusing the %s protocol.\n", ops->to_shortname); -} - -void -gr_mourn () -{ - gr_clear_all_breakpoints (); - unpush_target (gr_get_ops()); - generic_mourn_inferior (); -} - -void -gr_kill () -{ - return; -} - -/* This is called not only when we first attach, but also when the - user types "run" after having attached. */ -void -gr_create_inferior (execfile, args, env) - char *execfile; - char *args; - char **env; -{ - int entry_pt; - - if (args && *args) - error ("Can't pass arguments to remote process."); - - if (execfile == 0 || exec_bfd == 0) - error ("No exec file specified"); - - entry_pt = (int) bfd_get_start_address (exec_bfd); - sr_check_open (); - - gr_kill (); - gr_clear_all_breakpoints (); - - init_wait_for_inferior (); - gr_checkin(); - - insert_breakpoints (); /* Needed to get correct instruction in cache */ - proceed (entry_pt, -1, 0); -} - -/* Given a null terminated list of strings LIST, read the input until we find one of - them. Return the index of the string found or -1 on error. '?' means match - any single character. Note that with the algorithm we use, the initial - character of the string cannot recur in the string, or we will not find some - cases of the string in the input. If PASSTHROUGH is non-zero, then - pass non-matching data on. */ - -int -gr_multi_scan (list, passthrough) - char *list[]; - int passthrough; -{ - char *swallowed = NULL; /* holding area */ - char *swallowed_p = swallowed; /* Current position in swallowed. */ - int ch; - int ch_handled; - int i; - int string_count; - int max_length; - char **plist; - - /* Look through the strings. Count them. Find the largest one so we can - allocate a holding area. */ - - for (max_length = string_count = i = 0; - list[i] != NULL; - ++i, ++string_count) - { - int length = strlen(list[i]); - - if (length > max_length) - max_length = length; - } - - /* if we have no strings, then something is wrong. */ - if (string_count == 0) - return(-1); - - /* otherwise, we will need a holding area big enough to hold almost two - copies of our largest string. */ - swallowed_p = swallowed = alloca(max_length << 1); - - /* and a list of pointers to current scan points. */ - plist = (char **) alloca (string_count * sizeof(*plist)); - - /* and initialize */ - for (i = 0; i < string_count; ++i) - plist[i] = list[i]; - - for (ch = sr_readchar(); /* loop forever */ ; ch = sr_readchar()) - { - QUIT; /* Let user quit and leave process running */ - ch_handled = 0; - - for (i = 0; i < string_count; ++i) - { - if (ch == *plist[i] || *plist[i] == '?') - { - ++plist[i]; - if (*plist[i] == '\0') - return(i); - - if (!ch_handled) - *swallowed_p++ = ch; - - ch_handled = 1; - } - else - plist[i] = list[i]; - } - - if (!ch_handled) - { - char *p; - - /* Print out any characters which have been swallowed. */ - if (passthrough) - { - for (p = swallowed; p < swallowed_p; ++p) - fputc_unfiltered (*p, gdb_stdout); - - fputc_unfiltered (ch, gdb_stdout); - } - - swallowed_p = swallowed; - } - } -#if 0 - /* Never reached. */ - return(-1); -#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. */ - -void -gr_prepare_to_store () -{ - /* Do nothing, since we assume we can store individual regs */ -} - -/* Read a word from remote address ADDR and return it. - * This goes through the data cache. - */ -int -gr_fetch_word (addr) - CORE_ADDR addr; -{ - return dcache_fetch (gr_get_dcache(), addr); -} - -/* Write a word WORD into remote address ADDR. - This goes through the data cache. */ - -void -gr_store_word (addr, word) - CORE_ADDR addr; - int word; -{ - dcache_poke (gr_get_dcache(), addr, word); -} - -/* general purpose load a file specified on the command line - into target memory. */ - -void -gr_load_image (args, fromtty) - char *args; - int fromtty; -{ - bfd *abfd; - - asection *s; - struct cleanup *old_cleanups; - int delta = 4096; - char *buffer = xmalloc (delta); - - abfd = bfd_openr (args, (char *) 0); - - if (!abfd) - perror_with_name (args); - - old_cleanups = make_cleanup (bfd_close, abfd); - - QUIT; - - if (!bfd_check_format (abfd, bfd_object)) - error ("It doesn't seem to be an object file.\n"); - - for (s = abfd->sections; s && !quit_flag; s = s->next) - { - if (bfd_get_section_flags (abfd, s) & SEC_LOAD) - { - int i; - printf_filtered ("%s\t: 0x%4x .. 0x%4x ", - s->name, s->vma, s->vma + s->_raw_size); - fflush (stdout); - for (i = 0; i < s->_raw_size && !quit_flag; i += delta) - { - int sub_delta = delta; - if (sub_delta > s->_raw_size - i) - sub_delta = s->_raw_size - i; - QUIT; - bfd_get_section_contents (abfd, s, buffer, i, sub_delta); - target_write_memory (s->vma + i, buffer, sub_delta); - printf_filtered ("*"); - fflush (stdout); - } - printf_filtered ("\n"); - } - } - - free (buffer); - write_pc (bfd_get_start_address (abfd)); - bfd_close (abfd); - discard_cleanups (old_cleanups); -} - - -void -_initialize_sr_support () -{ -/* FIXME-now: if target is open... */ - add_show_from_set (add_set_cmd ("remotedevice", no_class, - var_filename, (char *)&sr_settings.device, - "Set device for remote serial I/O.\n\ -This device is used as the serial port when debugging using remote\n\ -targets.", &setlist), - &showlist); - - add_com ("remote ", class_obscure, sr_com, - "Send a command to the remote monitor."); - -} diff --git a/gnu/usr.bin/gdb/gdb/remote-utils.h b/gnu/usr.bin/gdb/gdb/remote-utils.h deleted file mode 100644 index d859330..0000000 --- a/gnu/usr.bin/gdb/gdb/remote-utils.h +++ /dev/null @@ -1,142 +0,0 @@ -/* Generic support for remote debugging interfaces. - - Copyright 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. */ - -#ifndef REMOTE_UTILS_H -#define REMOTE_UTILS_H - -#include "serial.h" -#include "target.h" -#include "dcache.h" - -/* Stuff that should be shared (and handled consistently) among the various - remote targets. */ - -struct _sr_settings { - unsigned int timeout; - - int retries; - - char *device; - serial_t desc; - -}; - -extern struct _sr_settings sr_settings; - -/* get and set debug value. */ -#define sr_get_debug() (remote_debug) -#define sr_set_debug(newval) (remote_debug = (newval)) - -/* get and set timeout. */ -#define sr_get_timeout() (sr_settings.timeout) -#define sr_set_timeout(newval) (sr_settings.timeout = (newval)) - -/* get and set device. */ -#define sr_get_device() (sr_settings.device) -#define sr_set_device(newval) \ -{ \ - if (sr_settings.device) free(sr_settings.device); \ - sr_settings.device = (newval); \ -} - -/* get and set descriptor value. */ -#define sr_get_desc() (sr_settings.desc) -#define sr_set_desc(newval) (sr_settings.desc = (newval)) - -/* get and set retries. */ -#define sr_get_retries() (sr_settings.retries) -#define sr_set_retries(newval) (sr_settings.retries = (newval)) - -#define sr_is_open() (sr_settings.desc != NULL) - -#define sr_check_open() { if (!sr_is_open()) \ - error ("Remote device not open"); } - -struct gr_settings { - /* This is our data cache. */ - DCACHE *dcache; - char *prompt; - struct target_ops *ops; - int (*clear_all_breakpoints)PARAMS((void)); - memxferfunc readfunc; - memxferfunc writefunc; - void (*checkin)PARAMS((void)); -}; - -extern struct gr_settings *gr_settings; - -/* get and set dcache. */ -#define gr_get_dcache() (gr_settings->dcache) -#define gr_set_dcache(newval) (gr_settings->dcache = (newval)) - -/* get and set prompt. */ -#define gr_get_prompt() (gr_settings->prompt) -#define gr_set_prompt(newval) (gr_settings->prompt = (newval)) - -/* get and set ops. */ -#define gr_get_ops() (gr_settings->ops) -#define gr_set_ops(newval) (gr_settings->ops = (newval)) - -#define gr_clear_all_breakpoints() ((gr_settings->clear_all_breakpoints)()) -#define gr_checkin() ((gr_settings->checkin)()) - -/* Keep discarding input until we see the prompt. - - The convention for dealing with the prompt is that you - 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 gr_expect_prompt(). Exception: 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 bug_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. */ - -#define gr_expect_prompt() sr_expect(gr_get_prompt()) - -int gr_fetch_word PARAMS((CORE_ADDR addr)); -int gr_multi_scan PARAMS((char *list[], int passthrough)); -int sr_get_hex_digit PARAMS((int ignore_space)); -int sr_pollchar PARAMS((void)); -int sr_readchar PARAMS((void)); -int sr_timed_read PARAMS((char *buf, int n)); -long sr_get_hex_word PARAMS((void)); -void gr_close PARAMS((int quitting)); -void gr_create_inferior PARAMS((char *execfile, char *args, char **env)); -void gr_detach PARAMS((char *args, int from_tty)); -void gr_files_info PARAMS((struct target_ops *ops)); -void gr_generic_checkin PARAMS((void)); -void gr_kill PARAMS((void)); -void gr_mourn PARAMS((void)); -void gr_prepare_to_store PARAMS((void)); -void gr_store_word PARAMS((CORE_ADDR addr, int word)); -void sr_expect PARAMS((char *string)); -void sr_get_hex_byte PARAMS((char *byt)); -void sr_scan_args PARAMS((char *proto, char *args)); -void sr_write PARAMS((char *a, int l)); -void sr_write_cr PARAMS((char *s)); - -void gr_open PARAMS((char *args, int from_tty, - struct gr_settings *gr_settings)); -void gr_load_image PARAMS((char*, int from_tty)); -#endif /* REMOTE_UTILS_H */ diff --git a/gnu/usr.bin/gdb/gdb/remote.c b/gnu/usr.bin/gdb/gdb/remote.c deleted file mode 100644 index c340ca9..0000000 --- a/gnu/usr.bin/gdb/gdb/remote.c +++ /dev/null @@ -1,1470 +0,0 @@ -/* Remote target communications for serial-line targets in custom GDB protocol - Copyright 1988, 1991, 1992, 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. */ - -/* Remote communication protocol. - - A debug packet whose contents are - is encapsulated for transmission in the form: - - $ # CSUM1 CSUM2 - - must be ASCII alphanumeric and cannot include characters - '$' or '#'. If starts with two characters followed by - ':', then the existing stubs interpret this as a sequence number. - - CSUM1 and CSUM2 are ascii hex representation of an 8-bit - checksum of , the most significant nibble is sent first. - the hex digits 0-9,a-f are used. - - Receiver responds with: - - + - if CSUM is correct and ready for next packet - - - if CSUM is incorrect - - is as follows: - All values are encoded in ascii hex digits. - - Request Packet - - read registers g - reply XX....X Each byte of register data - is described by two hex digits. - Registers are in the internal order - for GDB, and the bytes in a register - are in the same order the machine uses. - or ENN for an error. - - write regs GXX..XX Each byte of register data - is described by two hex digits. - reply OK for success - ENN for an error - - write reg Pn...=r... Write register n... with value r..., - which contains two hex digits for each - byte in the register (target byte - order). - reply OK for success - ENN for an error - (not supported by all stubs). - - read mem mAA..AA,LLLL AA..AA is address, LLLL is length. - reply XX..XX XX..XX is mem contents - Can be fewer bytes than requested - if able to read only part of the data. - or ENN NN is errno - - write mem MAA..AA,LLLL:XX..XX - AA..AA is address, - LLLL is number of bytes, - XX..XX is data - reply OK for success - ENN for an error (this includes the case - where only part of the data was - written). - - cont cAA..AA AA..AA is address to resume - If AA..AA is omitted, - resume at same address. - - step sAA..AA AA..AA is address to resume - If AA..AA is omitted, - resume at same address. - - last signal ? Reply the current reason for stopping. - This is the same reply as is generated - for step or cont : SAA where AA is the - signal number. - - There is no immediate reply to step or cont. - The reply comes when the machine stops. - It is SAA AA is the "signal number" - - or... TAAn...:r...;n:r...;n...:r...; - AA = signal number - n... = register number - r... = register contents - or... WAA The process exited, and AA is - the exit status. This is only - applicable for certains sorts of - targets. - kill request k - - toggle debug d toggle debug flag (see 386 & 68k stubs) - reset r reset -- see sparc stub. - reserved On other requests, the stub should - ignore the request and send an empty - response ($#). This way - we can extend the protocol and GDB - can tell whether the stub it is - talking to uses the old or the new. - search tAA:PP,MM Search backwards starting at address - AA for a match with pattern PP and - mask MM. PP and MM are 4 bytes. - Not supported by all stubs. - - general query qXXXX Request info about XXXX. - general set QXXXX=yyyy Set value of XXXX to yyyy. - query sect offs qOffsets Get section offsets. Reply is - Text=xxx;Data=yyy;Bss=zzz - console output Otext Send text to stdout. Only comes from - remote target. - - Responses can be run-length encoded to save space. A '*' means that - the next two characters are hex digits giving a repeat count which - stands for that many repititions of the character preceding the '*'. - Note that this means that responses cannot contain '*'. Example: - "0*03" means the same as "0000". */ - -#include "defs.h" -#include -#include -#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 "dcache.h" - -#if !defined(DONT_USE_REMOTE) -#ifdef USG -#include -#endif - -#include -#include "serial.h" - -/* Prototypes for local functions */ - -static int -remote_write_bytes PARAMS ((CORE_ADDR memaddr, unsigned char *myaddr, int len)); - -static int -remote_read_bytes PARAMS ((CORE_ADDR memaddr, unsigned char *myaddr, int len)); - -static void -remote_files_info PARAMS ((struct target_ops *ignore)); - -static int -remote_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len, - int should_write, struct target_ops *target)); - -static void -remote_prepare_to_store PARAMS ((void)); - -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 void -remote_open PARAMS ((char *name, int from_tty)); - -static void -remote_close PARAMS ((int quitting)); - -static void -remote_store_registers PARAMS ((int regno)); - -static void -getpkt PARAMS ((char *buf, int forever)); - -static void -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 -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 */ - -/* 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; - -#if 0 -int icache; -#endif - -/* 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; - -/* 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 - for writing large chunks of memory (e.g. in downloads). Also, this needs - to be more than 400 if required to hold the registers (see below, where - we round it up based on REGISTER_BYTES). */ -#define PBUFSIZ 400 - -/* 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) - -/* Round up PBUFSIZ to hold all the registers, at least. */ -/* The blank line after the #if seems to be required to work around a - bug in HP's PA compiler. */ -#if REGISTER_BYTES > MAXBUFBYTES - -#undef PBUFSIZ -#define PBUFSIZ (REGISTER_BYTES * 2 + 32) -#endif - -/* 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; - - -/* Clean up connection to a remote debugger. */ - -/* ARGSUSED */ -static void -remote_close (quitting) - int quitting; -{ - if (remote_desc) - SERIAL_CLOSE (remote_desc); - remote_desc = NULL; -} - -/* Query the remote side for the text, data and bss offsets. */ - -static void -get_offsets () -{ - unsigned char buf[PBUFSIZ]; - int nvals; - CORE_ADDR text_addr, data_addr, bss_addr; - struct section_offsets *offs; - - putpkt ("qOffsets"); - - getpkt (buf, 0); - - if (buf[0] == '\000') - 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) - error ("Malformed response to offset query, %s", buf); - - if (symfile_objfile == NULL) - return; - - offs = (struct section_offsets *) alloca (sizeof (struct section_offsets) - + symfile_objfile->num_sections - * sizeof (offs->offsets)); - memcpy (offs, symfile_objfile->section_offsets, - sizeof (struct section_offsets) - + symfile_objfile->num_sections - * sizeof (offs->offsets)); - - /* FIXME: This code assumes gdb-stabs.h is being used; it's broken - for xcoff, dwarf, sdb-coff, etc. But there is no simple - canonical representation for this stuff. (Just what does "text" - as seen by the stub mean, anyway? I think it means all sections - with SEC_CODE set, but we currently have no way to deal with that). */ - - ANOFFSET (offs, SECT_OFF_TEXT) = text_addr; - - /* This is a temporary kludge to force data and bss to use the same offsets - because that's what nlmconv does now. The real solution requires changes - to the stub and remote.c that I don't have time to do right now. */ - - ANOFFSET (offs, SECT_OFF_DATA) = data_addr; - ANOFFSET (offs, SECT_OFF_BSS) = data_addr; - - objfile_relocate (symfile_objfile, offs); -} - -/* Stub for catch_errors. */ - -static int -remote_start_remote (dummy) - char *dummy; -{ - immediate_quit = 1; /* Allow user to interrupt it */ - - /* Ack any packet which the remote side has already sent. */ - - SERIAL_WRITE (remote_desc, "+", 1); - - get_offsets (); /* Get text, data & bss offsets */ - - putpkt ("?"); /* initiate a query from remote machine */ - 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 *remote_dcache; - -static void -remote_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 (&remote_ops); - - remote_dcache = dcache_init (remote_read_bytes, remote_write_bytes); - - remote_desc = SERIAL_OPEN (name); - if (!remote_desc) - perror_with_name (name); - - if (baud_rate != -1) - { - if (SERIAL_SETBAUDRATE (remote_desc, baud_rate)) - { - SERIAL_CLOSE (remote_desc); - perror_with_name (name); - } - } - - SERIAL_RAW (remote_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 (remote_desc); - - if (from_tty) - { - puts_filtered ("Remote debugging using "); - puts_filtered (name); - puts_filtered ("\n"); - } - push_target (&remote_ops); /* 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. */ - stub_supports_P = 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 (remote_start_remote, (char *)0, - "Couldn't establish connection to remote target\n", RETURN_MASK_ALL)) - pop_target(); -} - -/* remote_detach() - takes a program previously attached to and detaches it. - We better not have left any breakpoints - in the program or it'll die when it hits one. - Close the open connection to the remote debugger. - Use this when you want to detach and do something else - with your gdb. */ - -static void -remote_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"); -} - -/* 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"); -} - -/* Convert number NIB to a hex digit. */ - -static int -tohex (nib) - int nib; -{ - if (nib < 10) - return '0'+nib; - else - return 'a'+nib-10; -} - -/* Tell the remote machine to resume. */ - -static void -remote_resume (pid, step, siggnal) - int pid, step; - enum target_signal siggnal; -{ - char buf[PBUFSIZ]; - - if (siggnal) - { - target_terminal_ours_for_output (); - printf_filtered - ("Can't send signals to a remote system. %s not sent.\n", - target_signal_to_name (siggnal)); - target_terminal_inferior (); - } - - dcache_flush (remote_dcache); - - strcpy (buf, step ? "s": "c"); - - putpkt (buf); -} - -/* Send ^C to target to halt it. Target will respond, and send us a - packet. */ - -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"); - - SERIAL_WRITE (remote_desc, "\003", 1); /* Send a ^C */ -} - -static void (*ofunc)(); - -/* The user typed ^C twice. */ -static void -remote_interrupt_twice (signo) - int signo; -{ - signal (signo, ofunc); - - interrupt_query (); - - signal (signo, remote_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 (); -} - -/* 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) - int pid; - struct target_waitstatus *status; -{ - unsigned char buf[PBUFSIZ]; - - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; - - while (1) - { - unsigned char *p; - - ofunc = (void (*)()) signal (SIGINT, remote_interrupt); - getpkt ((char *) buf, 1); - signal (SIGINT, ofunc); - - switch (buf[0]) - { - case 'E': /* Error of some sort */ - warning ("Remote failure reply: %s", buf); - continue; - case 'T': /* Status with PC, SP, FP, ... */ - { - int i; - long regno; - char regs[MAX_REGISTER_RAW_SIZE]; - - /* Expedited reply, containing Signal, {regno, reg} repeat */ - /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where - ss = signal number - n... = register number - r... = register contents - */ - - p = &buf[3]; /* after Txx */ - - while (*p) - { - unsigned char *p1; - - regno = strtol (p, &p1, 16); /* Read the register number */ - - if (p1 == p) - warning ("Remote sent badly formed register number: %s\nPacket: '%s'\n", - p1, buf); - - p = p1; - - if (*p++ != ':') - warning ("Malformed packet (missing colon): %s\nPacket: '%s'\n", - p, buf); - - if (regno >= NUM_REGS) - warning ("Remote sent bad register number %d: %s\nPacket: '%s'\n", - regno, p, buf); - - for (i = 0; i < REGISTER_RAW_SIZE (regno); i++) - { - if (p[0] == 0 || p[1] == 0) - warning ("Remote reply is too short: %s", buf); - regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]); - p += 2; - } - - if (*p++ != ';') - warning ("Remote register badly formatted: %s", buf); - - supply_register (regno, regs); - } - } - /* fall through */ - case 'S': /* Old style status, just signal only */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.sig = (enum target_signal) - (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))); - - return 0; - case 'W': /* Target exited */ - { - /* The remote process exited. */ - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]); - return 0; - } - case 'O': /* Console output */ - fputs_filtered (buf + 1, gdb_stdout); - continue; - default: - warning ("Invalid remote reply: %s", buf); - continue; - } - } - return 0; -} - -/* 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) - int regno; -{ - char buf[PBUFSIZ]; - int i; - char *p; - char regs[REGISTER_BYTES]; - - sprintf (buf, "g"); - remote_send (buf); - - /* Unimplemented registers read as all bits zero. */ - memset (regs, 0, REGISTER_BYTES); - - /* We can get out of synch in various cases. If the first character - 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')) - { - if (remote_debug) - printf_unfiltered ("Bad register packet; fetching a new packet\n"); - getpkt (buf, 0); - } - - /* Reply describes registers byte by byte, each byte encoded as two - hex characters. Suck them all up, then supply them to the - register cacheing/storage mechanism. */ - - p = buf; - for (i = 0; i < REGISTER_BYTES; i++) - { - if (p[0] == 0) - break; - if (p[1] == 0) - { - warning ("Remote reply is of odd length: %s", buf); - /* Don't change register_bytes_found in this case, and don't - print a second warning. */ - goto supply_them; - } - regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]); - p += 2; - } - - if (i != register_bytes_found) - { - register_bytes_found = i; -#ifdef REGISTER_BYTES_OK - if (!REGISTER_BYTES_OK (i)) - warning ("Remote reply is too short: %s", buf); -#endif - } - - supply_them: - for (i = 0; i < NUM_REGS; i++) - supply_register (i, ®s[REGISTER_BYTE(i)]); -} - -/* Prepare to store registers. Since we may send them all (using a - 'G' request), we have to read out the ones we don't want to change - first. */ - -static void -remote_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 -remote_store_registers (regno) - int regno; -{ - char buf[PBUFSIZ]; - int i; - char *p; - - if (regno >= 0 && stub_supports_P) - { - /* Try storing a single register. */ - char *regp; - - sprintf (buf, "P%x=", regno); - p = buf + strlen (buf); - regp = ®isters[REGISTER_BYTE (regno)]; - for (i = 0; i < REGISTER_RAW_SIZE (regno); ++i) - { - *p++ = tohex ((regp[i] >> 4) & 0xf); - *p++ = tohex (regp[i] & 0xf); - } - *p = '\0'; - remote_send (buf); - if (buf[0] != '\0') - { - /* The stub understands the 'P' request. We are done. */ - return; - } - - /* The stub does not support the 'P' request. Use 'G' instead, - and don't try using 'P' in the future (it will just waste our - time). */ - stub_supports_P = 0; - } - - buf[0] = 'G'; - - /* Command describes registers byte by byte, - each byte encoded as two hex characters. */ - - p = buf + 1; - /* remote_prepare_to_store insures that register_bytes_found gets set. */ - for (i = 0; i < register_bytes_found; i++) - { - *p++ = tohex ((registers[i] >> 4) & 0xf); - *p++ = tohex (registers[i] & 0xf); - } - *p = '\0'; - - remote_send (buf); -} - -#if 0 - -/* Use of the data cache is 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, but a better way which would - win for more cases would be to use the executable file for the text - segment, like the `icache' code below but done cleanly (in some - target-independent place, perhaps in target_xfer_memory, perhaps - based on assigning each target a speed or perhaps by some simpler - mechanism). */ - -/* Read a word from remote address ADDR and return it. - This goes through the data cache. */ - -static int -remote_fetch_word (addr) - CORE_ADDR addr; -{ -#if 0 - if (icache) - { - extern CORE_ADDR text_start, text_end; - - if (addr >= text_start && addr < text_end) - { - int buffer; - xfer_core_file (addr, &buffer, sizeof (int)); - return buffer; - } - } -#endif - return dcache_fetch (remote_dcache, addr); -} - -/* Write a word WORD into remote address ADDR. - This goes through the data cache. */ - -static void -remote_store_word (addr, word) - CORE_ADDR addr; - int word; -{ - dcache_poke (remote_dcache, addr, word); -} -#endif /* 0 */ - -/* 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 -remote_write_bytes (memaddr, myaddr, len) - CORE_ADDR memaddr; - unsigned char *myaddr; - int len; -{ - char buf[PBUFSIZ]; - int i; - char *p; - - /* 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, len); - - /* We send target system values byte by byte, in increasing byte addresses, - each byte encoded as two hex characters. */ - - p = buf + strlen (buf); - for (i = 0; i < len; i++) - { - *p++ = tohex ((myaddr[i] >> 4) & 0xf); - *p++ = tohex (myaddr[i] & 0xf); - } - *p = '\0'; - - putpkt (buf); - getpkt (buf, 0); - - if (buf[0] == 'E') - { - /* There is no correspondance between what the remote protocol uses - for errors and errno codes. We would like a cleaner way of - representing errors (big enough to include errno codes, bfd_error - codes, and others). But for now just return EIO. */ - errno = EIO; - return 0; - } - return 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 -remote_read_bytes (memaddr, myaddr, len) - CORE_ADDR memaddr; - unsigned char *myaddr; - int len; -{ - char buf[PBUFSIZ]; - int i; - char *p; - - if (len > PBUFSIZ / 2 - 1) - abort (); - - /* 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, len); - putpkt (buf); - getpkt (buf, 0); - - if (buf[0] == 'E') - { - /* There is no correspondance between what the remote protocol uses - for errors and errno codes. We would like a cleaner way of - representing errors (big enough to include errno codes, bfd_error - codes, and others). But for now just return EIO. */ - errno = EIO; - return 0; - } - - /* Reply describes memory byte by byte, - each byte encoded as two hex characters. */ - - p = buf; - for (i = 0; i < len; 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. */ - break; - myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]); - p += 2; - } - return i; -} - -/* 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) - CORE_ADDR memaddr; - char *myaddr; - int len; - int should_write; - struct target_ops *target; /* ignored */ -{ - int xfersize; - int bytes_xferred; - int total_xferred = 0; - - while (len > 0) - { - if (len > MAXBUFBYTES) - xfersize = MAXBUFBYTES; - else - xfersize = len; - - if (should_write) - bytes_xferred = remote_write_bytes (memaddr, - (unsigned char *)myaddr, xfersize); - else - bytes_xferred = remote_read_bytes (memaddr, - (unsigned char *)myaddr, xfersize); - - /* If we get an error, we are done xferring. */ - if (bytes_xferred == 0) - break; - - memaddr += bytes_xferred; - myaddr += bytes_xferred; - len -= bytes_xferred; - total_xferred += bytes_xferred; - } - return total_xferred; -} - -#if 0 -/* Enable after 4.12. */ - -void -remote_search (len, data, mask, startaddr, increment, lorange, hirange - addr_found, data_found) - int len; - char *data; - char *mask; - CORE_ADDR startaddr; - int increment; - CORE_ADDR lorange; - CORE_ADDR hirange; - CORE_ADDR *addr_found; - char *data_found; -{ - if (increment == -4 && len == 4) - { - long mask_long, data_long; - long data_found_long; - CORE_ADDR addr_we_found; - char buf[PBUFSIZ]; - long returned_long[2]; - char *p; - - mask_long = extract_unsigned_integer (mask, len); - data_long = extract_unsigned_integer (data, len); - sprintf (buf, "t%x:%x,%x", startaddr, data_long, mask_long); - putpkt (buf); - getpkt (buf, 0); - if (buf[0] == '\0') - { - /* The stub doesn't support the 't' request. We might want to - remember this fact, but on the other hand the stub could be - switched on us. Maybe we should remember it only until - the next "target remote". */ - generic_search (len, data, mask, startaddr, increment, lorange, - hirange, addr_found, data_found); - return; - } - - if (buf[0] == 'E') - /* There is no correspondance between what the remote protocol uses - for errors and errno codes. We would like a cleaner way of - representing errors (big enough to include errno codes, bfd_error - codes, and others). But for now just use EIO. */ - memory_error (EIO, startaddr); - p = buf; - addr_we_found = 0; - while (*p != '\0' && *p != ',') - addr_we_found = (addr_we_found << 4) + fromhex (*p++); - if (*p == '\0') - error ("Protocol error: short return for search"); - - data_found_long = 0; - while (*p != '\0' && *p != ',') - data_found_long = (data_found_long << 4) + fromhex (*p++); - /* Ignore anything after this comma, for future extensions. */ - - if (addr_we_found < lorange || addr_we_found >= hirange) - { - *addr_found = 0; - return; - } - - *addr_found = addr_we_found; - *data_found = store_unsigned_integer (data_we_found, len); - return; - } - generic_search (len, data, mask, startaddr, increment, lorange, - hirange, addr_found, data_found); -} -#endif /* 0 */ - -static void -remote_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 end, masking it down to 7 bits. */ - -static int -readchar (timeout) - int timeout; -{ - int ch; - - ch = SERIAL_READCHAR (remote_desc, timeout); - - 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; - } -} - -/* 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) - char *buf; -{ - - putpkt (buf); - getpkt (buf, 0); - - if (buf[0] == 'E') - error ("Remote failure reply: %s", buf); -} - -/* Send a packet to the remote machine, with error checking. - The data of the packet is in BUF. */ - -static void -putpkt (buf) - char *buf; -{ - int i; - unsigned char csum = 0; - char buf2[PBUFSIZ]; - int cnt = strlen (buf); - int ch; - char *p; - - /* Copy the packet into buffer BUF2, encapsulating it - and giving it a checksum. */ - - if (cnt > sizeof(buf2) - 5) /* Prosanity check */ - abort(); - - p = buf2; - *p++ = '$'; - - for (i = 0; i < cnt; i++) - { - csum += buf[i]; - *p++ = buf[i]; - } - *p++ = '#'; - *p++ = tohex ((csum >> 4) & 0xf); - *p++ = tohex (csum & 0xf); - - /* 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 packet: %s...", buf2); - gdb_flush(gdb_stdout); - } - if (SERIAL_WRITE (remote_desc, buf2, p - buf2)) - perror_with_name ("putpkt: write failed"); - - /* read until either a timeout occurs (-2) or '+' is read */ - while (1) - { - ch = readchar (remote_timeout); - - if (remote_debug) - { - switch (ch) - { - case '+': - case SERIAL_TIMEOUT: - case '$': - if (started_error_output) - { - putc_unfiltered ('\n'); - started_error_output = 0; - } - } - } - - switch (ch) - { - case '+': - if (remote_debug) - printf_unfiltered("Ack\n"); - return; - case SERIAL_TIMEOUT: - break; /* Retransmit buffer */ - case '$': - { - unsigned char junkbuf[PBUFSIZ]; - - /* 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 + */ - } - default: - if (remote_debug) - { - if (!started_error_output) - { - started_error_output = 1; - printf_unfiltered ("putpkt: Junk: "); - } - putc_unfiltered (ch & 0177); - } - continue; - } - break; /* Here to retransmit */ - } - -#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. */ - if (quit_flag) - { - quit_flag = 0; - interrupt_query (); - } -#endif - } -} - -/* 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) - char *buf; -{ - unsigned char csum; - char *bp; - int c; - - csum = 0; - bp = buf; - - while (1) - { - c = readchar (remote_timeout); - - switch (c) - { - case SERIAL_TIMEOUT: - if (remote_debug) - puts_filtered ("Timeout in mid-packet, 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 '#': - { - unsigned char pktcsum; - - *bp = '\000'; - - pktcsum = fromhex (readchar (remote_timeout)) << 4 - | fromhex (readchar (remote_timeout)); - - if (csum == pktcsum) - return 1; - - printf_filtered ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=", - pktcsum, csum); - puts_filtered (buf); - puts_filtered ("\n"); - - return 0; - } - case '*': /* Run length encoding */ - c = readchar (remote_timeout); - csum += c; - c = c - ' ' + 3; /* Compute repeat count */ - - if (bp + c - 1 < buf + PBUFSIZ - 1) - { - memset (bp, *(bp - 1), c); - bp += c; - continue; - } - - *bp = '\0'; - printf_filtered ("Repeat count %d too large for buffer: ", c); - puts_filtered (buf); - puts_filtered ("\n"); - - return 0; - default: - if (bp < buf + PBUFSIZ - 1) - { - *bp++ = c; - csum += c; - continue; - } - - *bp = '\0'; - puts_filtered ("Remote packet 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 void -getpkt (buf, forever) - char *buf; - int forever; -{ - char *bp; - int c; - int tries; - int timeout; - int val; - - if (forever) - timeout = -1; - else - timeout = remote_timeout; - -#define MAX_TRIES 10 - - 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 remote_timeout intervals. */ - - do - { - c = readchar (timeout); - - if (c == SERIAL_TIMEOUT) - { - if (remote_debug) - puts_filtered ("Timed out.\n"); - goto retry; - } - } - while (c != '$'); - - /* We've found the start of a packet, now collect the data. */ - - val = read_frame (buf); - - if (val == 1) - { - if (remote_debug) - fprintf_unfiltered (gdb_stderr, "Packet received: %s\n", buf); - SERIAL_WRITE (remote_desc, "+", 1); - return; - } - - /* Try the whole thing again. */ -retry: - SERIAL_WRITE (remote_desc, "-", 1); - } - - /* We have tried hard enough, and just can't receive the packet. Give up. */ - - printf_unfiltered ("Ignoring packet error, continuing...\n"); - SERIAL_WRITE (remote_desc, "+", 1); -} - -static void -remote_kill () -{ - putpkt ("k"); - /* 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. */ - target_mourn_inferior (); -} - -static void -remote_mourn () -{ - unpush_target (&remote_ops); - generic_mourn_inferior (); -} - -#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; - -/* Check that it fits in BREAKPOINT_MAX bytes. */ -static unsigned char check_break_insn_size[BREAKPOINT_MAX] = REMOTE_BREAKPOINT; - -#else /* No REMOTE_BREAKPOINT. */ - -/* Same old breakpoint instruction. This code does nothing different - than mem-break.c. */ -static unsigned char break_insn[] = BREAKPOINT; - -#endif /* No 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, - 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 - by the caller to be long enough to save sizeof BREAKPOINT bytes (this - is accomplished via BREAKPOINT_MAX). */ - -static int -remote_insert_breakpoint (addr, contents_cache) - CORE_ADDR addr; - char *contents_cache; -{ - int val; - - val = target_read_memory (addr, contents_cache, sizeof break_insn); - - if (val == 0) - val = target_write_memory (addr, (char *)break_insn, sizeof break_insn); - - return val; -} - -static int -remote_remove_breakpoint (addr, contents_cache) - CORE_ADDR addr; - char *contents_cache; -{ - return target_write_memory (addr, contents_cache, sizeof break_insn); -} - -/* 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 */ - 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 */ -}; -#endif /* Use remote. */ - -void -_initialize_remote () -{ -#if !defined(DONT_USE_REMOTE) - add_target (&remote_ops); -#endif -} diff --git a/gnu/usr.bin/gdb/gdb/ser-unix.c b/gnu/usr.bin/gdb/gdb/ser-unix.c deleted file mode 100644 index 1e5e1a6..0000000 --- a/gnu/usr.bin/gdb/gdb/ser-unix.c +++ /dev/null @@ -1,684 +0,0 @@ -/* Serial interface for local (hardwired) serial ports on Un*x like systems - Copyright 1992, 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. */ - -#include "defs.h" -#include "serial.h" -#include -#include - -#if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY) -#define HAVE_SGTTY -#endif - -#ifdef HAVE_TERMIOS -#include -#include - -struct hardwire_ttystate -{ - struct termios termios; -}; -#endif /* termios */ - -#ifdef HAVE_TERMIO -#include - -/* It is believed that all systems which have added job control to SVR3 - (e.g. sco) have also added termios. Even if not, trying to figure out - all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty - bewildering. So we don't attempt it. */ - -struct hardwire_ttystate -{ - struct termio termio; -}; -#endif /* termio */ - -#ifdef HAVE_SGTTY -/* Needed for the code which uses select(). We would include - too if it existed on all systems. */ -#include - -#include - -struct hardwire_ttystate -{ - struct sgttyb sgttyb; - struct tchars tc; - struct ltchars ltc; - /* Line discipline flags. */ - int lmode; -}; -#endif /* sgtty */ - -static int hardwire_open PARAMS ((serial_t scb, const char *name)); -static void hardwire_raw PARAMS ((serial_t scb)); -static int wait_for PARAMS ((serial_t scb, int timeout)); -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)); - -/* Open up a real live device for serial I/O */ - -static int -hardwire_open(scb, name) - serial_t scb; - const char *name; -{ - scb->fd = open (name, O_RDWR); - if (scb->fd < 0) - return -1; - - return 0; -} - -static int -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; - - return 0; -#endif - -#ifdef HAVE_TERMIO - if (ioctl (scb->fd, TCGETA, &state->termio) < 0) - return -1; - return 0; -#endif - -#ifdef HAVE_SGTTY - if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0) - return -1; - if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0) - return -1; - if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0) - return -1; - if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0) - return -1; - - return 0; -#endif -} - -static int -set_tty_state(scb, state) - serial_t scb; - struct hardwire_ttystate *state; -{ -#ifdef HAVE_TERMIOS - if (tcsetattr(scb->fd, TCSANOW, &state->termios) < 0) - return -1; - - return 0; -#endif - -#ifdef HAVE_TERMIO - if (ioctl (scb->fd, TCSETA, &state->termio) < 0) - return -1; - return 0; -#endif - -#ifdef HAVE_SGTTY - if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0) - return -1; - if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0) - return -1; - if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0) - return -1; - if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0) - return -1; - - return 0; -#endif -} - -static serial_ttystate -hardwire_get_tty_state(scb) - serial_t scb; -{ - struct hardwire_ttystate *state; - - state = (struct hardwire_ttystate *)xmalloc(sizeof *state); - - if (get_tty_state(scb, state)) - return NULL; - - return (serial_ttystate)state; -} - -static int -hardwire_set_tty_state(scb, ttystate) - serial_t scb; - serial_ttystate ttystate; -{ - struct hardwire_ttystate *state; - - state = (struct hardwire_ttystate *)ttystate; - - return set_tty_state(scb, state); -} - -static int -hardwire_noflush_set_tty_state (scb, new_ttystate, old_ttystate) - serial_t scb; - serial_ttystate new_ttystate; - serial_ttystate old_ttystate; -{ - struct hardwire_ttystate new_state; - struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate; - - new_state = *(struct hardwire_ttystate *)new_ttystate; - - /* Don't change in or out of raw mode; we don't want to flush input. - termio and termios have no such restriction; for them flushing input - is separate from setting the attributes. */ - -#ifdef HAVE_SGTTY - if (state->sgttyb.sg_flags & RAW) - new_state.sgttyb.sg_flags |= RAW; - else - new_state.sgttyb.sg_flags &= ~RAW; - - /* I'm not sure whether this is necessary; the manpage just mentions - RAW not CBREAK. */ - if (state->sgttyb.sg_flags & CBREAK) - new_state.sgttyb.sg_flags |= CBREAK; - else - new_state.sgttyb.sg_flags &= ~CBREAK; -#endif - - return set_tty_state (scb, &new_state); -} - -static void -hardwire_print_tty_state (scb, ttystate) - serial_t scb; - serial_ttystate ttystate; -{ - struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate; - int i; - -#ifdef HAVE_TERMIOS - printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n", - state->termios.c_iflag, state->termios.c_oflag); - printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x\n", - state->termios.c_cflag, state->termios.c_lflag); -#if 0 - /* This not in POSIX, and is not really documented by those systems - which have it (at least not Sun). */ - printf_filtered ("c_line = 0x%x.\n", state->termios.c_line); -#endif - printf_filtered ("c_cc: "); - for (i = 0; i < NCCS; i += 1) - printf_filtered ("0x%x ", state->termios.c_cc[i]); - printf_filtered ("\n"); -#endif - -#ifdef HAVE_TERMIO - printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n", - state->termio.c_iflag, state->termio.c_oflag); - printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n", - state->termio.c_cflag, state->termio.c_lflag, - state->termio.c_line); - printf_filtered ("c_cc: "); - for (i = 0; i < NCC; i += 1) - printf_filtered ("0x%x ", state->termio.c_cc[i]); - printf_filtered ("\n"); -#endif - -#ifdef HAVE_SGTTY - printf_filtered ("sgttyb.sg_flags = 0x%x.\n", state->sgttyb.sg_flags); - - printf_filtered ("tchars: "); - for (i = 0; i < (int)sizeof (struct tchars); i++) - printf_filtered ("0x%x ", ((unsigned char *)&state->tc)[i]); - printf_filtered ("\n"); - - printf_filtered ("ltchars: "); - for (i = 0; i < (int)sizeof (struct ltchars); i++) - printf_filtered ("0x%x ", ((unsigned char *)&state->ltc)[i]); - printf_filtered ("\n"); - - printf_filtered ("lmode: 0x%x\n", state->lmode); -#endif -} - -static int -hardwire_flush_output (scb) - serial_t scb; -{ -#ifdef HAVE_TERMIOS - return tcflush (scb->fd, TCOFLUSH); -#endif - -#ifdef HAVE_TERMIO - return ioctl (scb->fd, TCFLSH, 1); -#endif - -#ifdef HAVE_SGTTY - /* This flushes both input and output, but we can't do better. */ - return ioctl (scb->fd, TIOCFLUSH, 0); -#endif -} - -static int -hardwire_flush_input (scb) - serial_t scb; -{ -#ifdef HAVE_TERMIOS - return tcflush (scb->fd, TCIFLUSH); -#endif - -#ifdef HAVE_TERMIO - return ioctl (scb->fd, TCFLSH, 0); -#endif - -#ifdef HAVE_SGTTY - /* This flushes both input and output, but we can't do better. */ - return ioctl (scb->fd, TIOCFLUSH, 0); -#endif -} - -static int -hardwire_send_break (scb) - serial_t scb; -{ -#ifdef HAVE_TERMIOS - return tcsendbreak (scb->fd, 0); -#endif - -#ifdef HAVE_TERMIO - return ioctl (scb->fd, TCSBRK, 0); -#endif - -#ifdef HAVE_SGTTY - { - int status; - struct timeval timeout; - - status = ioctl (scb->fd, TIOCSBRK, 0); - - /* Can't use usleep; it doesn't exist in BSD 4.2. */ - /* Note that if this select() is interrupted by a signal it will not wait - the full length of time. I think that is OK. */ - timeout.tv_sec = 0; - timeout.tv_usec = 250000; - select (0, 0, 0, 0, &timeout); - status = ioctl (scb->fd, TIOCCBRK, 0); - return status; - } -#endif -} - -static void -hardwire_raw(scb) - serial_t scb; -{ - struct hardwire_ttystate state; - - if (get_tty_state(scb, &state)) - fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno)); - -#ifdef HAVE_TERMIOS - state.termios.c_iflag = 0; - state.termios.c_oflag = 0; - state.termios.c_lflag = 0; - state.termios.c_cflag &= ~(CSIZE|PARENB); - state.termios.c_cflag |= CLOCAL | CS8; - state.termios.c_cc[VMIN] = 0; - state.termios.c_cc[VTIME] = 0; -#endif - -#ifdef HAVE_TERMIO - state.termio.c_iflag = 0; - state.termio.c_oflag = 0; - state.termio.c_lflag = 0; - state.termio.c_cflag &= ~(CSIZE|PARENB); - state.termio.c_cflag |= CLOCAL | CS8; - state.termio.c_cc[VMIN] = 0; - state.termio.c_cc[VTIME] = 0; -#endif - -#ifdef HAVE_SGTTY - state.sgttyb.sg_flags |= RAW | ANYP; - state.sgttyb.sg_flags &= ~(CBREAK | ECHO); -#endif - - scb->current_timeout = 0; - - if (set_tty_state (scb, &state)) - fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno)); -} - -/* Wait for input on scb, with timeout seconds. Returns 0 on success, - otherwise SERIAL_TIMEOUT or SERIAL_ERROR. - - For termio{s}, we actually just setup VTIME if necessary, and let the - timeout occur in the read() in hardwire_read(). - */ - -static int -wait_for(scb, timeout) - serial_t scb; - int timeout; -{ - scb->timeout_remaining = 0; - -#ifdef HAVE_SGTTY - { - struct timeval tv; - fd_set readfds; - - FD_ZERO (&readfds); - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - FD_SET(scb->fd, &readfds); - - while (1) - { - int numfds; - - if (timeout >= 0) - numfds = select(scb->fd+1, &readfds, 0, 0, &tv); - else - numfds = select(scb->fd+1, &readfds, 0, 0, 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 */ - - return 0; - } - } -#endif /* HAVE_SGTTY */ - -#if defined HAVE_TERMIO || defined HAVE_TERMIOS - if (timeout == scb->current_timeout) - return 0; - - scb->current_timeout = timeout; - - { - struct hardwire_ttystate state; - - if (get_tty_state(scb, &state)) - fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno)); - -#ifdef HAVE_TERMIOS - if (timeout < 0) - { - /* No timeout. */ - state.termios.c_cc[VTIME] = 0; - state.termios.c_cc[VMIN] = 1; - } - else - { - state.termios.c_cc[VMIN] = 0; - state.termios.c_cc[VTIME] = timeout * 10; - if (state.termios.c_cc[VTIME] != timeout * 10) - { - - /* If c_cc is an 8-bit signed character, we can't go - bigger than this. If it is always unsigned, we could use - 25. */ - - scb->current_timeout = 12; - state.termios.c_cc[VTIME] = scb->current_timeout * 10; - scb->timeout_remaining = timeout - scb->current_timeout; - } - } -#endif - -#ifdef HAVE_TERMIO - if (timeout < 0) - { - /* No timeout. */ - state.termio.c_cc[VTIME] = 0; - state.termio.c_cc[VMIN] = 1; - } - else - { - state.termio.c_cc[VMIN] = 0; - state.termio.c_cc[VTIME] = timeout * 10; - if (state.termio.c_cc[VTIME] != timeout * 10) - { - /* If c_cc is an 8-bit signed character, we can't go - bigger than this. If it is always unsigned, we could use - 25. */ - - scb->current_timeout = 12; - state.termio.c_cc[VTIME] = scb->current_timeout * 10; - scb->timeout_remaining = timeout - scb->current_timeout; - } - } -#endif - - if (set_tty_state (scb, &state)) - fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno)); - - return 0; - } -#endif /* HAVE_TERMIO || HAVE_TERMIOS */ -} - -/* Read a character with user-specified timeout. TIMEOUT is number of seconds - 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) - serial_t scb; - int timeout; -{ - int status; - - if (scb->bufcnt-- > 0) - return *scb->bufp++; - - while (1) - { - status = wait_for (scb, timeout); - - if (status < 0) - return status; - - scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ); - - if (scb->bufcnt <= 0) - { - if (scb->bufcnt == 0) - { - /* Zero characters means timeout (it could also be EOF, but - we don't (yet at least) distinguish). */ - if (scb->timeout_remaining > 0) - { - timeout = scb->timeout_remaining; - continue; - } - else - return SERIAL_TIMEOUT; - } - else if (errno == EINTR) - continue; - else - return SERIAL_ERROR; /* Got an error from read */ - } - - scb->bufcnt--; - scb->bufp = scb->buf; - return *scb->bufp++; - } -} - -#ifndef B19200 -#define B19200 EXTA -#endif - -#ifndef B38400 -#define B38400 EXTB -#endif - -/* Translate baud rates from integers to damn B_codes. Unix should - have outgrown this crap years ago, but even POSIX wouldn't buck it. */ - -static struct -{ - int rate; - int code; -} -baudtab[] = -{ - {50, B50}, - {75, B75}, - {110, B110}, - {134, B134}, - {150, B150}, - {200, B200}, - {300, B300}, - {600, B600}, - {1200, B1200}, - {1800, B1800}, - {2400, B2400}, - {4800, B4800}, - {9600, B9600}, - {19200, B19200}, - {38400, B38400}, - {-1, -1}, -}; - -static int -rate_to_code(rate) - int rate; -{ - int i; - - for (i = 0; baudtab[i].rate != -1; i++) - if (rate == baudtab[i].rate) - return baudtab[i].code; - - return -1; -} - -static int -hardwire_setbaudrate(scb, rate) - serial_t scb; - int rate; -{ - struct hardwire_ttystate state; - - if (get_tty_state(scb, &state)) - return -1; - -#ifdef HAVE_TERMIOS - cfsetospeed (&state.termios, rate_to_code (rate)); - cfsetispeed (&state.termios, rate_to_code (rate)); -#endif - -#ifdef HAVE_TERMIO -#ifndef CIBAUD -#define CIBAUD CBAUD -#endif - - state.termio.c_cflag &= ~(CBAUD | CIBAUD); - state.termio.c_cflag |= rate_to_code (rate); -#endif - -#ifdef HAVE_SGTTY - state.sgttyb.sg_ispeed = rate_to_code (rate); - state.sgttyb.sg_ospeed = rate_to_code (rate); -#endif - - return set_tty_state (scb, &state); -} - -static int -hardwire_write(scb, str, len) - serial_t scb; - const char *str; - int len; -{ - int cc; - - while (len > 0) - { - cc = write(scb->fd, str, len); - - if (cc < 0) - return 1; - len -= cc; - str += cc; - } - return 0; -} - -static void -hardwire_close(scb) - serial_t scb; -{ - if (scb->fd < 0) - return; - - close(scb->fd); - scb->fd = -1; -} - -static struct serial_ops hardwire_ops = -{ - "hardwire", - 0, - hardwire_open, - hardwire_close, - hardwire_readchar, - hardwire_write, - hardwire_flush_output, - hardwire_flush_input, - hardwire_send_break, - hardwire_raw, - hardwire_get_tty_state, - hardwire_set_tty_state, - hardwire_print_tty_state, - hardwire_noflush_set_tty_state, - hardwire_setbaudrate, -}; - -void -_initialize_ser_hardwire () -{ - serial_add_interface (&hardwire_ops); -} diff --git a/gnu/usr.bin/gdb/gdb/serial.c b/gnu/usr.bin/gdb/gdb/serial.c deleted file mode 100644 index e15b0c8..0000000 --- a/gnu/usr.bin/gdb/gdb/serial.c +++ /dev/null @@ -1,265 +0,0 @@ -/* Generic serial interface routines - Copyright 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. */ - -#include "defs.h" -#include "serial.h" - -/* Linked list of serial I/O handlers */ - -static struct serial_ops *serial_ops_list = NULL; - -/* This is the last serial stream opened. Used by connect command. */ - -static serial_t last_serial_opened = NULL; - -static struct serial_ops * -serial_interface_lookup (name) - char *name; -{ - struct serial_ops *ops; - - for (ops = serial_ops_list; ops; ops = ops->next) - if (strcmp (name, ops->name) == 0) - return ops; - - return NULL; -} - -void -serial_add_interface(optable) - struct serial_ops *optable; -{ - optable->next = serial_ops_list; - serial_ops_list = optable; -} - -/* Open up a device or a network socket, depending upon the syntax of NAME. */ - -serial_t -serial_open (name) - const char *name; -{ - serial_t scb; - struct serial_ops *ops; - - if (strcmp (name, "pc") == 0) - ops = serial_interface_lookup ("pc"); - else if (strchr (name, ':')) - ops = serial_interface_lookup ("tcp"); - else - ops = serial_interface_lookup ("hardwire"); - - if (!ops) - return NULL; - - scb = (serial_t)xmalloc (sizeof (struct _serial_t)); - - scb->ops = ops; - - scb->bufcnt = 0; - scb->bufp = scb->buf; - - if (scb->ops->open(scb, name)) - { - free (scb); - return NULL; - } - - last_serial_opened = scb; - - return scb; -} - -serial_t -serial_fdopen(fd) - const int fd; -{ - serial_t scb; - struct serial_ops *ops; - - ops = serial_interface_lookup ("hardwire"); - - if (!ops) - return NULL; - - scb = (serial_t)xmalloc (sizeof (struct _serial_t)); - - scb->ops = ops; - - scb->bufcnt = 0; - scb->bufp = scb->buf; - - scb->fd = fd; - - last_serial_opened = scb; - - return scb; -} - -void -serial_close(scb) - serial_t scb; -{ - last_serial_opened = NULL; - -/* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you - should fix your code instead. */ - - if (!scb) - return; - - scb->ops->close(scb); - free(scb); -} - -#if 0 -/* -The connect command is #if 0 because I hadn't thought of an elegant -way to wait for I/O on two serial_t's simultaneously. Two solutions -came to mind: - - 1) Fork, and have have one fork handle the to user direction, - and have the other hand the to target direction. This - obviously won't cut it for MSDOS. - - 2) Use something like select. This assumes that stdin and - the target side can both be waited on via the same - mechanism. This may not be true for DOS, if GDB is - talking to the target via a TCP socket. --grossman, 8 Jun 93 -*/ - -/* Connect the user directly to the remote system. This command acts just like - the 'cu' or 'tip' command. Use ~. or ~^D to break out. */ - -static serial_t tty_desc; /* Controlling terminal */ - -static void -cleanup_tty(ttystate) - serial_ttystate ttystate; -{ - printf_unfiltered ("\r\n[Exiting connect mode]\r\n"); - SERIAL_SET_TTY_STATE (tty_desc, ttystate); - free (ttystate); - SERIAL_CLOSE (tty_desc); -} - -static void -connect_command (args, fromtty) - char *args; - int fromtty; -{ - int c; - char cur_esc = 0; - serial_ttystate ttystate; - serial_t port_desc; /* TTY port */ - - dont_repeat(); - - if (args) - fprintf_unfiltered(gdb_stderr, "This command takes no args. They have been ignored.\n"); - - printf_unfiltered("[Entering connect mode. Use ~. or ~^D to escape]\n"); - - tty_desc = SERIAL_FDOPEN (0); - port_desc = last_serial_opened; - - ttystate = SERIAL_GET_TTY_STATE (tty_desc); - - SERIAL_RAW (tty_desc); - SERIAL_RAW (port_desc); - - make_cleanup (cleanup_tty, ttystate); - - while (1) - { - int mask; - - mask = SERIAL_WAIT_2 (tty_desc, port_desc, -1); - - if (mask & 2) - { /* tty input */ - char cx; - - while (1) - { - c = SERIAL_READCHAR(tty_desc, 0); - - if (c == SERIAL_TIMEOUT) - break; - - if (c < 0) - perror_with_name("connect"); - - cx = c; - SERIAL_WRITE(port_desc, &cx, 1); - - switch (cur_esc) - { - case 0: - if (c == '\r') - cur_esc = c; - break; - case '\r': - if (c == '~') - cur_esc = c; - else - cur_esc = 0; - break; - case '~': - if (c == '.' || c == '\004') - return; - else - cur_esc = 0; - } - } - } - - if (mask & 1) - { /* Port input */ - char cx; - - while (1) - { - c = SERIAL_READCHAR(port_desc, 0); - - if (c == SERIAL_TIMEOUT) - break; - - if (c < 0) - perror_with_name("connect"); - - cx = c; - - SERIAL_WRITE(tty_desc, &cx, 1); - } - } - } -} -#endif /* 0 */ - -void -_initialize_serial () -{ -#if 0 - add_com ("connect", class_obscure, connect_command, - "Connect the terminal directly up to the command monitor.\n\ -Use ~. or ~^D to break out."); -#endif /* 0 */ -} diff --git a/gnu/usr.bin/gdb/gdb/serial.h b/gnu/usr.bin/gdb/gdb/serial.h deleted file mode 100644 index 9e669cb..0000000 --- a/gnu/usr.bin/gdb/gdb/serial.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Remote serial support interface definitions for GDB, the GNU Debugger. - Copyright 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. */ - -#ifndef SERIAL_H -#define SERIAL_H - -/* Terminal state pointer. This is specific to each type of interface. */ - -typedef PTR serial_ttystate; - -struct _serial_t -{ - int fd; /* File descriptor */ - struct serial_ops *ops; /* Function vector */ - serial_ttystate ttystate; /* Not used (yet) */ - int bufcnt; /* Amount of data in receive buffer */ - unsigned char *bufp; /* Current byte */ - unsigned char buf[BUFSIZ]; /* Da buffer itself */ - int current_timeout; /* (termio{s} only), last value of VTIME */ - /* ser-unix.c termio{,s} only, we still need to wait for this many more - seconds. */ - int timeout_remaining; -}; - -typedef struct _serial_t *serial_t; - -struct serial_ops { - char *name; - struct serial_ops *next; - int (*open) PARAMS ((serial_t, const char *name)); - void (*close) PARAMS ((serial_t)); - int (*readchar) PARAMS ((serial_t, int timeout)); - int (*write) PARAMS ((serial_t, const char *str, int len)); - int (*flush_output) PARAMS ((serial_t)); - int (*flush_input) PARAMS ((serial_t)); - int (*send_break) PARAMS ((serial_t)); - void (*go_raw) PARAMS ((serial_t)); - serial_ttystate (*get_tty_state) PARAMS ((serial_t)); - int (*set_tty_state) PARAMS ((serial_t, serial_ttystate)); - void (*print_tty_state) PARAMS ((serial_t, serial_ttystate)); - int (*noflush_set_tty_state) - PARAMS ((serial_t, serial_ttystate, serial_ttystate)); - int (*setbaudrate) PARAMS ((serial_t, int rate)); -}; - -/* Add a new serial interface to the interface list */ - -void serial_add_interface PARAMS ((struct serial_ops *optable)); - -serial_t serial_open PARAMS ((const char *name)); - -serial_t serial_fdopen PARAMS ((const int fd)); - -/* For most routines, if a failure is indicated, then errno should be - examined. */ - -/* Try to open NAME. Returns a new serial_t on success, NULL on failure. - */ - -#define SERIAL_OPEN(NAME) serial_open(NAME) - -/* Open a new serial stream using a file handle. */ - -#define SERIAL_FDOPEN(FD) serial_fdopen(FD) - -/* Flush pending output. Might also flush input (if this system can't flush - only output). */ - -#define SERIAL_FLUSH_OUTPUT(SERIAL_T) \ - ((SERIAL_T)->ops->flush_output((SERIAL_T))) - -/* Flush pending input. Might also flush output (if this system can't flush - only input). */ - -#define SERIAL_FLUSH_INPUT(SERIAL_T)\ - ((*(SERIAL_T)->ops->flush_input) ((SERIAL_T))) - -/* Send a break between 0.25 and 0.5 seconds long. */ - -#define SERIAL_SEND_BREAK(SERIAL_T) \ - ((*(SERIAL_T)->ops->send_break) (SERIAL_T)) - -/* Turn the port into raw mode. */ - -#define SERIAL_RAW(SERIAL_T) (SERIAL_T)->ops->go_raw((SERIAL_T)) - -/* Return a pointer to a newly malloc'd ttystate containing the state - of the tty. */ -#define SERIAL_GET_TTY_STATE(SERIAL_T) (SERIAL_T)->ops->get_tty_state((SERIAL_T)) - -/* Set the state of the tty to TTYSTATE. The change is immediate. - When changing to or from raw mode, input might be discarded. - Returns 0 for success, negative value for error (in which case errno - contains the error). */ -#define SERIAL_SET_TTY_STATE(SERIAL_T, TTYSTATE) (SERIAL_T)->ops->set_tty_state((SERIAL_T), (TTYSTATE)) - -/* printf_filtered a user-comprehensible description of ttystate. */ -#define SERIAL_PRINT_TTY_STATE(SERIAL_T, TTYSTATE) \ - ((*((SERIAL_T)->ops->print_tty_state)) ((SERIAL_T), (TTYSTATE))) - -/* Set the tty state to NEW_TTYSTATE, where OLD_TTYSTATE is the - current state (generally obtained from a recent call to - SERIAL_GET_TTY_STATE), but be careful not to discard any input. - This means that we never switch in or out of raw mode, even - if NEW_TTYSTATE specifies a switch. */ -#define SERIAL_NOFLUSH_SET_TTY_STATE(SERIAL_T, NEW_TTYSTATE, OLD_TTYSTATE) \ - ((*((SERIAL_T)->ops->noflush_set_tty_state)) \ - ((SERIAL_T), (NEW_TTYSTATE), (OLD_TTYSTATE))) - -/* Read one char from the serial device with TIMEOUT seconds to wait - or -1 to wait forever. Use timeout of 0 to effect a poll. Returns - char if ok, else one of the following codes. Note that all error - codes are guaranteed to be < 0. */ - -#define SERIAL_ERROR -1 /* General error, see errno for details */ -#define SERIAL_TIMEOUT -2 -#define SERIAL_EOF -3 - -#define SERIAL_READCHAR(SERIAL_T, TIMEOUT) ((SERIAL_T)->ops->readchar((SERIAL_T), TIMEOUT)) - -/* Set the baudrate to the decimal value supplied. Returns 0 for success, - -1 for failure. */ - -#define SERIAL_SETBAUDRATE(SERIAL_T, RATE) ((SERIAL_T)->ops->setbaudrate((SERIAL_T), RATE)) - -/* Write LEN chars from STRING to the port SERIAL_T. Returns 0 for - success, non-zero for failure. */ - -#define SERIAL_WRITE(SERIAL_T, STRING, LEN) ((SERIAL_T)->ops->write((SERIAL_T), STRING, LEN)) - -/* Push out all buffers, close the device and destroy SERIAL_T. */ - -void serial_close PARAMS ((serial_t)); - -#define SERIAL_CLOSE(SERIAL_T) serial_close(SERIAL_T) - -/* Destroy SERIAL_T without doing the rest of the stuff that SERIAL_CLOSE - does. */ - -#define SERIAL_UN_FDOPEN(SERIAL_T) (free (SERIAL_T)) - -#endif /* SERIAL_H */ diff --git a/gnu/usr.bin/gdb/gdb/signals.h b/gnu/usr.bin/gdb/gdb/signals.h deleted file mode 100644 index 08fa606..0000000 --- a/gnu/usr.bin/gdb/gdb/signals.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Signal handler definitions for GDB, the GNU Debugger. - Copyright (C) 1986, 1989 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. */ - - -/* This file is almost the same as including except that it - eliminates certain signal names when job control is not supported, - (or, on some systems, when job control is there but doesn't work - the way GDB expects it to work). */ -/* This has been superceded by the job_control variable in serial.h. */ - -#include diff --git a/gnu/usr.bin/gdb/gdb/solib.c b/gnu/usr.bin/gdb/gdb/solib.c deleted file mode 100644 index 55eaba7..0000000 --- a/gnu/usr.bin/gdb/gdb/solib.c +++ /dev/null @@ -1,1549 +0,0 @@ -/* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger. - Copyright 1990, 1991, 1992, 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. */ - - -#include "defs.h" - -#include -#include -#include -#ifdef __FreeBSD__ -#include -#endif -#include -#include -#include - -#ifndef SVR4_SHARED_LIBS - /* SunOS shared libs need the nlist structure. */ -#include -#else -#include "libelf.h" -#ifndef DT_MIPS_RLD_MAP -#include "elf/mips.h" -#endif -#endif - -#include "symtab.h" -#include "bfd.h" -#include "symfile.h" -#include "objfiles.h" -#include "gdbcore.h" -#include "command.h" -#include "target.h" -#include "frame.h" -#include "gnuregex.h" -#include "inferior.h" -#include "language.h" - -#define MAX_PATH_SIZE 256 /* FIXME: Should be dynamic */ - -/* On SVR4 systems, for the initial implementation, use some runtime startup - symbol as the "startup mapping complete" breakpoint address. The models - for SunOS and SVR4 dynamic linking debugger support are different in that - SunOS hits one breakpoint when all mapping is complete while using the SVR4 - debugger support takes two breakpoint hits for each file mapped, and - there is no way to know when the "last" one is hit. Both these - mechanisms should be tied to a "breakpoint service routine" that - gets automatically executed whenever one of the breakpoints indicating - a change in mapping is hit. This is a future enhancement. (FIXME) */ - -#define BKPT_AT_SYMBOL 1 - -#if defined (BKPT_AT_SYMBOL) && defined (SVR4_SHARED_LIBS) -static char *bkpt_names[] = { -#ifdef SOLIB_BKPT_NAME - SOLIB_BKPT_NAME, /* Prefer configured name if it exists. */ -#endif - "_start", - "main", - NULL -}; -#endif - -/* Symbols which are used to locate the base of the link map structures. */ - -#ifndef SVR4_SHARED_LIBS -static char *debug_base_symbols[] = { - "_DYNAMIC", - NULL -}; -#endif - -/* local data declarations */ - -#ifndef SVR4_SHARED_LIBS - -#define LM_ADDR(so) ((so) -> lm.lm_addr) -#define LM_NEXT(so) ((so) -> lm.lm_next) -#define LM_NAME(so) ((so) -> lm.lm_name) -/* Test for first link map entry; first entry is a shared library. */ -#define IGNORE_FIRST_LINK_MAP_ENTRY(x) (0) -static struct link_dynamic dynamic_copy; -static struct link_dynamic_2 ld_2_copy; -static struct ld_debug debug_copy; -static CORE_ADDR debug_addr; -static CORE_ADDR flag_addr; - -#else /* SVR4_SHARED_LIBS */ - -#define LM_ADDR(so) ((so) -> lm.l_addr) -#define LM_NEXT(so) ((so) -> lm.l_next) -#define LM_NAME(so) ((so) -> lm.l_name) -/* Test for first link map entry; first entry is the exec-file. */ -#define IGNORE_FIRST_LINK_MAP_ENTRY(x) ((x).l_prev == NULL) -static struct r_debug debug_copy; -char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */ - -#endif /* !SVR4_SHARED_LIBS */ - -struct so_list { - struct so_list *next; /* next structure in linked list */ - struct link_map lm; /* copy of link map from inferior */ - struct link_map *lmaddr; /* addr in inferior lm was read from */ - CORE_ADDR lmend; /* upper addr bound of mapped object */ - char so_name[MAX_PATH_SIZE]; /* shared object lib name (FIXME) */ - char symbols_loaded; /* flag: symbols read in yet? */ - char from_tty; /* flag: print msgs? */ - struct objfile *objfile; /* objfile for loaded lib */ - struct section_table *sections; - struct section_table *sections_end; - struct section_table *textsection; - bfd *abfd; -}; - -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 */ - -extern int -fdmatch PARAMS ((int, int)); /* In libiberty */ - -/* Local function prototypes */ - -static void -special_symbol_handling PARAMS ((struct so_list *)); - -static void -sharedlibrary_command PARAMS ((char *, int)); - -static int -enable_break PARAMS ((void)); - -static int -disable_break PARAMS ((void)); - -static void -info_sharedlibrary_command PARAMS ((char *, int)); - -static int -symbol_add_stub PARAMS ((char *)); - -static struct so_list * -find_solib PARAMS ((struct so_list *)); - -static struct link_map * -first_link_map_member PARAMS ((void)); - -static CORE_ADDR -locate_base PARAMS ((void)); - -static void -solib_map_sections PARAMS ((struct so_list *)); - -#ifdef SVR4_SHARED_LIBS - -static CORE_ADDR -elf_locate_base PARAMS ((void)); - -#else - -static void -solib_add_common_symbols PARAMS ((struct rtc_symb *, struct objfile *)); - -#endif - -/* - -LOCAL FUNCTION - - solib_map_sections -- open bfd and build sections for shared lib - -SYNOPSIS - - static void solib_map_sections (struct so_list *so) - -DESCRIPTION - - Given a pointer to one of the shared objects in our list - of mapped objects, use the recorded name to open a bfd - descriptor for the object, build a section table, and then - relocate all the section addresses by the base address at - which the shared object was mapped. - -FIXMES - - In most (all?) cases the shared object file name recorded in the - dynamic linkage tables will be a fully qualified pathname. For - cases where it isn't, do we really mimic the systems search - mechanism correctly in the below code (particularly the tilde - expansion stuff?). - */ - -static void -solib_map_sections (so) - struct so_list *so; -{ - char *filename; - char *scratch_pathname; - int scratch_chan; - struct section_table *p; - struct cleanup *old_chain; - bfd *abfd; - - filename = tilde_expand (so -> so_name); - old_chain = make_cleanup (free, filename); - - scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, - &scratch_pathname); - if (scratch_chan < 0) - { - scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename, - O_RDONLY, 0, &scratch_pathname); - } - if (scratch_chan < 0) - { - perror_with_name (filename); - } - /* Leave scratch_pathname allocated. abfd->name will point to it. */ - - abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan); - if (!abfd) - { - close (scratch_chan); - error ("Could not open `%s' as an executable file: %s", - scratch_pathname, bfd_errmsg (bfd_get_error ())); - } - /* Leave bfd open, core_xfer_memory and "info files" need it. */ - so -> abfd = abfd; - abfd -> cacheable = true; - - if (!bfd_check_format (abfd, bfd_object)) - { - error ("\"%s\": not in executable format: %s.", - scratch_pathname, bfd_errmsg (bfd_get_error ())); - } - if (build_section_table (abfd, &so -> sections, &so -> sections_end)) - { - error ("Can't find the file sections in `%s': %s", - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - } - - for (p = so -> sections; p < so -> sections_end; p++) - { - /* Relocate the section binding addresses as recorded in the shared - object's file by the base address to which the object was actually - mapped. */ - p -> addr += (CORE_ADDR) LM_ADDR (so); - p -> endaddr += (CORE_ADDR) LM_ADDR (so); - so -> lmend = (CORE_ADDR) max (p -> endaddr, so -> lmend); - if (STREQ (p -> the_bfd_section -> name, ".text")) - { - so -> textsection = p; - } - } - - /* Free the file names, close the file now. */ - do_cleanups (old_chain); -} - -/* Read all dynamically loaded common symbol definitions from the inferior - and add them to the minimal symbol table for the shared library objfile. */ - -#ifndef SVR4_SHARED_LIBS - -/* In GDB 4.9 this routine was a real performance hog. According to - some gprof data which mtranle@paris.IntelliCorp.COM (Minh Tran-Le) - sent, almost all the time spend in solib_add (up to 20 minutes with - 35 shared libraries) was spent here, with 5/6 in - lookup_minimal_symbol and 1/6 in read_memory. - - To fix this, we moved the call to special_symbol_handling out of the - loop in solib_add, so this only gets called once, rather than once - for every shared library, and also removed the call to lookup_minimal_symbol - in this routine. */ - -static void -solib_add_common_symbols (rtc_symp, objfile) - struct rtc_symb *rtc_symp; - struct objfile *objfile; -{ - struct rtc_symb inferior_rtc_symb; - struct nlist inferior_rtc_nlist; - int len; - char *name; - char *origname; - - init_minimal_symbol_collection (); - make_cleanup (discard_minimal_symbols, 0); - - while (rtc_symp) - { - read_memory ((CORE_ADDR) rtc_symp, - (char *) &inferior_rtc_symb, - sizeof (inferior_rtc_symb)); - read_memory ((CORE_ADDR) inferior_rtc_symb.rtc_sp, - (char *) &inferior_rtc_nlist, - sizeof(inferior_rtc_nlist)); - if (inferior_rtc_nlist.n_type == N_COMM) - { - /* FIXME: The length of the symbol name is not available, but in the - current implementation the common symbol is allocated immediately - behind the name of the symbol. */ - len = inferior_rtc_nlist.n_value - inferior_rtc_nlist.n_un.n_strx; - - origname = name = xmalloc (len); - read_memory ((CORE_ADDR) inferior_rtc_nlist.n_un.n_name, name, len); - - /* Don't enter the symbol twice if the target is re-run. */ - - if (name[0] == bfd_get_symbol_leading_char (objfile->obfd)) - { - name++; - } - -#if 0 - /* I think this is unnecessary, GDB can probably deal with - duplicate minimal symbols, more or less. And the duplication - which used to happen because this was called for each shared - library is gone now that we are just called once. */ - /* FIXME: Do we really want to exclude symbols which happen - to match symbols for other locations in the inferior's - address space, even when they are in different linkage units? */ - if (lookup_minimal_symbol (name, (struct objfile *) NULL) == NULL) -#endif - { - name = obsavestring (name, strlen (name), - &objfile -> symbol_obstack); - prim_record_minimal_symbol (name, inferior_rtc_nlist.n_value, - mst_bss, objfile); - } - free (origname); - } - rtc_symp = inferior_rtc_symb.rtc_next; - } - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); -} - -#endif /* SVR4_SHARED_LIBS */ - - -#ifdef SVR4_SHARED_LIBS - -#ifdef HANDLE_SVR4_EXEC_EMULATORS - -/* - Solaris BCP (the part of Solaris which allows it to run SunOS4 - a.out files) throws in another wrinkle. Solaris does not fill - in the usual a.out link map structures when running BCP programs, - the only way to get at them is via groping around in the dynamic - linker. - The dynamic linker and it's structures are located in the shared - C library, which gets run as the executable's "interpreter" by - the kernel. - - Note that we can assume nothing about the process state at the time - we need to find these structures. We may be stopped on the first - instruction of the interpreter (C shared library), the first - instruction of the executable itself, or somewhere else entirely - (if we attached to the process for example). -*/ - -static char *debug_base_symbols[] = { - "r_debug", /* Solaris 2.3 */ - "_r_debug", /* Solaris 2.1, 2.2 */ - NULL -}; - -static int -look_for_base PARAMS ((int, CORE_ADDR)); - -static CORE_ADDR -bfd_lookup_symbol PARAMS ((bfd *, char *)); - -/* - -LOCAL FUNCTION - - bfd_lookup_symbol -- lookup the value for a specific symbol - -SYNOPSIS - - CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname) - -DESCRIPTION - - An expensive way to lookup the value of a single symbol for - bfd's that are only temporary anyway. This is used by the - shared library support to find the address of the debugger - interface structures in the shared library. - - Note that 0 is specifically allowed as an error return (no - such symbol). -*/ - -static CORE_ADDR -bfd_lookup_symbol (abfd, symname) - bfd *abfd; - char *symname; -{ - unsigned int storage_needed; - asymbol *sym; - asymbol **symbol_table; - unsigned int number_of_symbols; - unsigned int i; - struct cleanup *back_to; - CORE_ADDR symaddr = 0; - - storage_needed = bfd_get_symtab_upper_bound (abfd); - - if (storage_needed > 0) - { - symbol_table = (asymbol **) xmalloc (storage_needed); - back_to = make_cleanup (free, (PTR)symbol_table); - number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); - - for (i = 0; i < number_of_symbols; i++) - { - sym = *symbol_table++; - if (STREQ (sym -> name, symname)) - { - /* Bfd symbols are section relative. */ - symaddr = sym -> value + sym -> section -> vma; - break; - } - } - do_cleanups (back_to); - } - return (symaddr); -} - -/* - -LOCAL FUNCTION - - look_for_base -- examine file for each mapped address segment - -SYNOPSYS - - static int look_for_base (int fd, CORE_ADDR baseaddr) - -DESCRIPTION - - This function is passed to proc_iterate_over_mappings, which - causes it to get called once for each mapped address space, with - an open file descriptor for the file mapped to that space, and the - base address of that mapped space. - - Our job is to find the debug base symbol in the file that this - fd is open on, if it exists, and if so, initialize the dynamic - linker structure base address debug_base. - - Note that this is a computationally expensive proposition, since - we basically have to open a bfd on every call, so we specifically - avoid opening the exec file. - */ - -static int -look_for_base (fd, baseaddr) - int fd; - CORE_ADDR baseaddr; -{ - bfd *interp_bfd; - CORE_ADDR address = 0; - char **symbolp; - - /* If the fd is -1, then there is no file that corresponds to this - mapped memory segment, so skip it. Also, if the fd corresponds - to the exec file, skip it as well. */ - - if (fd == -1 - || (exec_bfd != NULL - && fdmatch (fileno ((GDB_FILE *)(exec_bfd -> iostream)), fd))) - { - return (0); - } - - /* Try to open whatever random file this fd corresponds to. Note that - we have no way currently to find the filename. Don't gripe about - any problems we might have, just fail. */ - - if ((interp_bfd = bfd_fdopenr ("unnamed", gnutarget, fd)) == NULL) - { - return (0); - } - if (!bfd_check_format (interp_bfd, bfd_object)) - { - bfd_close (interp_bfd); - return (0); - } - - /* Now try to find our debug base symbol in this file, which we at - least know to be a valid ELF executable or shared library. */ - - for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++) - { - address = bfd_lookup_symbol (interp_bfd, *symbolp); - if (address != 0) - { - break; - } - } - if (address == 0) - { - bfd_close (interp_bfd); - return (0); - } - - /* Eureka! We found the symbol. But now we may need to relocate it - by the base address. If the symbol's value is less than the base - address of the shared library, then it hasn't yet been relocated - by the dynamic linker, and we have to do it ourself. FIXME: Note - that we make the assumption that the first segment that corresponds - to the shared library has the base address to which the library - was relocated. */ - - if (address < baseaddr) - { - address += baseaddr; - } - debug_base = address; - bfd_close (interp_bfd); - return (1); -} -#endif /* HANDLE_SVR4_EXEC_EMULATORS */ - -/* - -LOCAL FUNCTION - - elf_locate_base -- locate the base address of dynamic linker structs - for SVR4 elf targets. - -SYNOPSIS - - CORE_ADDR elf_locate_base (void) - -DESCRIPTION - - For SVR4 elf targets the address of the dynamic linker's runtime - structure is contained within the dynamic info section in the - executable file. The dynamic section is also mapped into the - inferior address space. Because the runtime loader fills in the - real address before starting the inferior, we have to read in the - dynamic info section from the inferior address space. - If there are any errors while trying to find the address, we - silently return 0, otherwise the found address is returned. - - */ - -static CORE_ADDR -elf_locate_base () -{ - struct elf_internal_shdr *dyninfo_sect; - int dyninfo_sect_size; - CORE_ADDR dyninfo_addr; - char *buf; - char *bufend; - - /* Find the start address of the .dynamic section. */ - dyninfo_sect = bfd_elf_find_section (exec_bfd, ".dynamic"); - if (dyninfo_sect == NULL) - return 0; - dyninfo_addr = dyninfo_sect->sh_addr; - - /* Read in .dynamic section, silently ignore errors. */ - dyninfo_sect_size = dyninfo_sect->sh_size; - buf = alloca (dyninfo_sect_size); - if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size)) - return 0; - - /* 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. */ - for (bufend = buf + dyninfo_sect_size; - buf < bufend; - buf += sizeof (Elf32_External_Dyn)) - { - Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *)buf; - long dyn_tag; - CORE_ADDR dyn_ptr; - - dyn_tag = bfd_h_get_32 (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_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr); - return dyn_ptr; - } - else if (dyn_tag == DT_MIPS_RLD_MAP) - { - char pbuf[TARGET_PTR_BIT / HOST_CHAR_BIT]; - - /* DT_MIPS_RLD_MAP contains a pointer to the address - of the dynamic link structure. */ - dyn_ptr = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr); - if (target_read_memory (dyn_ptr, pbuf, sizeof (pbuf))) - return 0; - return extract_unsigned_integer (pbuf, sizeof (pbuf)); - } - } - - /* DT_DEBUG entry not found. */ - return 0; -} - -#endif /* SVR4_SHARED_LIBS */ - -/* - -LOCAL FUNCTION - - locate_base -- locate the base address of dynamic linker structs - -SYNOPSIS - - CORE_ADDR locate_base (void) - -DESCRIPTION - - For both the SunOS and SVR4 shared library implementations, if the - inferior executable has been linked dynamically, there is a single - address somewhere in the inferior's data space which is the key to - locating all of the dynamic linker's runtime structures. This - address is the value of the debug base symbol. The job of this - function is to find and return that address, or to return 0 if there - is no such address (the executable is statically linked for example). - - For SunOS, the job is almost trivial, since the dynamic linker and - all of it's structures are statically linked to the executable at - link time. Thus the symbol for the address we are looking for has - already been added to the minimal symbol table for the executable's - objfile at the time the symbol file's symbols were read, and all we - have to do is look it up there. Note that we explicitly do NOT want - to find the copies in the shared library. - - The SVR4 version is a bit more complicated because the address - is contained somewhere in the dynamic info section. We have to go - to a lot more work to discover the address of the debug base symbol. - Because of this complexity, we cache the value we find and return that - value on subsequent invocations. Note there is no copy in the - executable symbol tables. - - */ - -static CORE_ADDR -locate_base () -{ - -#ifndef SVR4_SHARED_LIBS - - struct minimal_symbol *msymbol; - CORE_ADDR address = 0; - char **symbolp; - - /* For SunOS, we want to limit the search for the debug base symbol to the - executable being debugged, since there is a duplicate named symbol in the - shared library. We don't want the shared library versions. */ - - for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++) - { - msymbol = lookup_minimal_symbol (*symbolp, symfile_objfile); - if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0)) - { - address = SYMBOL_VALUE_ADDRESS (msymbol); - return (address); - } - } - return (0); - -#else /* SVR4_SHARED_LIBS */ - - /* Check to see if we have a currently valid address, and if so, avoid - doing all this work again and just return the cached address. If - we have no cached address, try to locate it in the dynamic info - section for ELF executables. */ - - if (debug_base == 0) - { - if (exec_bfd != NULL - && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour) - debug_base = elf_locate_base (); -#ifdef HANDLE_SVR4_EXEC_EMULATORS - /* Try it the hard way for emulated executables. */ - else if (inferior_pid != 0) - proc_iterate_over_mappings (look_for_base); -#endif - } - return (debug_base); - -#endif /* !SVR4_SHARED_LIBS */ - -} - -/* - -LOCAL FUNCTION - - first_link_map_member -- locate first member in dynamic linker's map - -SYNOPSIS - - static struct link_map *first_link_map_member (void) - -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. -*/ - -static struct link_map * -first_link_map_member () -{ - struct link_map *lm = NULL; - -#ifndef SVR4_SHARED_LIBS - - read_memory (debug_base, (char *) &dynamic_copy, sizeof (dynamic_copy)); - if (dynamic_copy.ld_version >= 2) - { - /* It is a version that we can deal with, so read in the secondary - structure and find the address of the link map list from it. */ - read_memory ((CORE_ADDR) dynamic_copy.ld_un.ld_2, (char *) &ld_2_copy, - sizeof (struct link_dynamic_2)); - lm = ld_2_copy.ld_loaded; - } - -#else /* SVR4_SHARED_LIBS */ - - read_memory (debug_base, (char *) &debug_copy, sizeof (struct r_debug)); - /* FIXME: Perhaps we should validate the info somehow, perhaps by - checking r_version for a known version number, or r_state for - RT_CONSISTENT. */ - lm = debug_copy.r_map; - -#endif /* !SVR4_SHARED_LIBS */ - - return (lm); -} - -/* - -LOCAL FUNCTION - - find_solib -- step through list of shared objects - -SYNOPSIS - - struct so_list *find_solib (struct so_list *so_list_ptr) - -DESCRIPTION - - This module contains the routine which finds the names of any - loaded "images" in the current process. The argument in must be - NULL on the first call, and then the returned value must be passed - in on subsequent calls. This provides the capability to "step" down - the list of loaded objects. On the last object, a NULL value is - returned. - - The arg and return value are "struct link_map" pointers, as defined - in . - */ - -static struct so_list * -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 link_map *lm = NULL; - struct so_list *new; - - if (so_list_ptr == NULL) - { - /* 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 (); - } - } - } - 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 = LM_NEXT (so_list_ptr)) == 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 -> lmaddr, - (char *) &(so_list_ptr -> lm), - sizeof (struct link_map)); - if (status == 0) - { - lm = LM_NEXT (so_list_ptr); - } - else - { - lm = NULL; - } - } - so_list_next = so_list_ptr -> next; - } - if ((so_list_next == NULL) && (lm != NULL)) - { - /* 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 -> lmaddr = 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) - { - so_list_ptr -> next = new; - } - else - { - so_list_head = new; - } - so_list_next = new; - read_memory ((CORE_ADDR) lm, (char *) &(new -> lm), - sizeof (struct link_map)); - /* For SVR4 versions, the first entry in the link map is for the - inferior executable, so we must ignore it. For some versions of - SVR4, it has no name. For others (Solaris 2.3 for example), it - does have a name, so we can no longer use a missing name to - decide when to ignore it. */ - if (!IGNORE_FIRST_LINK_MAP_ENTRY (new -> lm)) - { - int errcode; - char *buffer; - 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)); - strncpy (new -> so_name, buffer, MAX_PATH_SIZE - 1); - new -> so_name[MAX_PATH_SIZE - 1] = '\0'; - free (buffer); - solib_map_sections (new); - } - } - return (so_list_next); -} - -/* A small stub to get us past the arg-passing pinhole of catch_errors. */ - -static int -symbol_add_stub (arg) - char *arg; -{ - register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */ - - so -> objfile = - symbol_file_add (so -> so_name, so -> from_tty, - (so->textsection == NULL - ? 0 - : (unsigned int) so -> textsection -> addr), - 0, 0, 0); - return (1); -} - -/* - -GLOBAL FUNCTION - - solib_add -- add a shared library file to the symtab and section list - -SYNOPSIS - - void solib_add (char *arg_string, int from_tty, - struct target_ops *target) - -DESCRIPTION - -*/ - -void -solib_add (arg_string, from_tty, target) - char *arg_string; - int from_tty; - struct target_ops *target; -{ - register struct so_list *so = NULL; /* link map state variable */ - - /* Last shared library that we read. */ - struct so_list *so_last = NULL; - - char *re_err; - int count; - int old; - - if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL) - { - error ("Invalid regexp: %s", re_err); - } - - /* Add the shared library sections to the section table of the - specified target, if any. We have to do this before reading the - symbol files as symbol_file_add calls reinit_frame_cache and - creating a new frame might access memory in the shared library. */ - if (target) - { - /* Count how many new section_table entries there are. */ - so = NULL; - count = 0; - while ((so = find_solib (so)) != NULL) - { - if (so -> so_name[0]) - { - count += so -> sections_end - so -> sections; - } - } - - if (count) - { - /* Reallocate the target's section table including the new size. */ - 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)) * (count + old)); - } - else - { - old = 0; - target -> to_sections = (struct section_table *) - xmalloc ((sizeof (struct section_table)) * count); - } - target -> to_sections_end = target -> to_sections + (count + old); - - /* Add these section table entries to the target's table. */ - while ((so = find_solib (so)) != NULL) - { - if (so -> so_name[0]) - { - count = so -> sections_end - so -> sections; - memcpy ((char *) (target -> to_sections + old), - so -> sections, - (sizeof (struct section_table)) * count); - old += count; - } - } - } - } - - /* Now add the symbol files. */ - while ((so = find_solib (so)) != NULL) - { - 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 -> so_name); - } - } - else if (catch_errors - (symbol_add_stub, (char *) so, - "Error while reading shared library symbols:\n", - RETURN_MASK_ALL)) - { - so_last = so; - so -> symbols_loaded = 1; - } - } - } - - /* Calling this once at the end means that we put all the minimal - symbols for commons into the objfile for the last shared library. - Since they are in common, this should not be a problem. If we - delete the objfile with the minimal symbols, we can put all the - symbols into a new objfile (and will on the next call to solib_add). - - An alternate approach would be to create an objfile just for - common minsyms, thus not needing any objfile argument to - solib_add_common_symbols. */ - - if (so_last) - special_symbol_handling (so_last); -} - -/* - -LOCAL FUNCTION - - info_sharedlibrary_command -- code for "info sharedlibrary" - -SYNOPSIS - - static void info_sharedlibrary_command () - -DESCRIPTION - - Walk through the shared library list and print information - about each attached library. -*/ - -static void -info_sharedlibrary_command (ignore, from_tty) - char *ignore; - int from_tty; -{ - register struct so_list *so = NULL; /* link map state variable */ - int header_done = 0; - - if (exec_bfd == NULL) - { - printf_unfiltered ("No exec file.\n"); - return; - } - 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"); - header_done++; - } - /* FIXME-32x64: need print_address_numeric with field width or - some such. */ - printf_unfiltered ("%-12s", - local_hex_string_custom ((unsigned long) LM_ADDR (so), - "08l")); - printf_unfiltered ("%-12s", - local_hex_string_custom ((unsigned long) so -> lmend, - "08l")); - printf_unfiltered ("%-12s", so -> symbols_loaded ? "Yes" : "No"); - printf_unfiltered ("%s\n", so -> so_name); - } - } - if (so_list_head == NULL) - { - printf_unfiltered ("No shared libraries loaded at this time.\n"); - } -} - -/* - -GLOBAL FUNCTION - - solib_address -- check to see if an address is in a shared lib - -SYNOPSIS - - int solib_address (CORE_ADDR address) - -DESCRIPTION - - Provides a hook for other gdb routines to discover whether or - not a particular address is within the mapped address space of - a shared library. Any address between the base mapping address - and the first address beyond the end of the last mapping, is - considered to be within the shared library address space, for - our purposes. - - For example, this routine is called at one point to disable - breakpoints which are in shared libraries that are not currently - mapped in. - */ - -int -solib_address (address) - CORE_ADDR address; -{ - register struct so_list *so = 0; /* link map state variable */ - - while ((so = find_solib (so)) != NULL) - { - if (so -> so_name[0]) - { - if ((address >= (CORE_ADDR) LM_ADDR (so)) && - (address < (CORE_ADDR) so -> lmend)) - { - return (1); - } - } - } - return (0); -} - -/* Called by free_all_symtabs */ - -void -clear_solib() -{ - struct so_list *next; - char *bfd_filename; - - while (so_list_head) - { - if (so_list_head -> sections) - { - free ((PTR)so_list_head -> sections); - } - if (so_list_head -> abfd) - { - bfd_filename = bfd_get_filename (so_list_head -> abfd); - bfd_close (so_list_head -> abfd); - } - else - /* This happens for the executable on SVR4. */ - bfd_filename = NULL; - - next = so_list_head -> next; - if (bfd_filename) - free ((PTR)bfd_filename); - free ((PTR)so_list_head); - so_list_head = next; - } - debug_base = 0; -} - -/* - -LOCAL FUNCTION - - disable_break -- remove the "mapping changed" breakpoint - -SYNOPSIS - - static int disable_break () - -DESCRIPTION - - Removes the breakpoint that gets hit when the dynamic linker - completes a mapping change. - -*/ - -static int -disable_break () -{ - int status = 1; - -#ifndef SVR4_SHARED_LIBS - - int in_debugger = 0; - - /* Read the debugger structure from the inferior to retrieve the - address of the breakpoint and the original contents of the - breakpoint address. Remove the breakpoint by writing the original - contents back. */ - - read_memory (debug_addr, (char *) &debug_copy, sizeof (debug_copy)); - - /* Set `in_debugger' to zero now. */ - - write_memory (flag_addr, (char *) &in_debugger, sizeof (in_debugger)); - - breakpoint_addr = (CORE_ADDR) debug_copy.ldd_bp_addr; - write_memory (breakpoint_addr, (char *) &debug_copy.ldd_bp_inst, - sizeof (debug_copy.ldd_bp_inst)); - -#else /* SVR4_SHARED_LIBS */ - - /* Note that breakpoint address and original contents are in our address - space, so we just need to write the original contents back. */ - - if (memory_remove_breakpoint (breakpoint_addr, shadow_contents) != 0) - { - status = 0; - } - -#endif /* !SVR4_SHARED_LIBS */ - - /* For the SVR4 version, we always know the breakpoint address. For the - SunOS version we don't know it until the above code is executed. - Grumble if we are stopped anywhere besides the breakpoint address. */ - - if (stop_pc != breakpoint_addr) - { - warning ("stopped at unknown breakpoint while handling shared libraries"); - } - - return (status); -} - -/* - -LOCAL FUNCTION - - enable_break -- arrange for dynamic linker to hit breakpoint - -SYNOPSIS - - int enable_break (void) - -DESCRIPTION - - Both the SunOS and the SVR4 dynamic linkers have, as part of their - debugger interface, support for arranging for the inferior to hit - a breakpoint after mapping in the shared libraries. This function - enables that breakpoint. - - For SunOS, there is a special flag location (in_debugger) which we - set to 1. When the dynamic linker sees this flag set, it will set - a breakpoint at a location known only to itself, after saving the - original contents of that place and the breakpoint address itself, - in it's own internal structures. When we resume the inferior, it - will eventually take a SIGTRAP when it runs into the breakpoint. - We handle this (in a different place) by restoring the contents of - the breakpointed location (which is only known after it stops), - chasing around to locate the shared libraries that have been - loaded, then resuming. - - For SVR4, the debugger interface structure contains a member (r_brk) - which is statically initialized at the time the shared library is - built, to the offset of a function (_r_debug_state) which is guaran- - teed to be called once before mapping in a library, and again when - the mapping is complete. At the time we are examining this member, - it contains only the unrelocated offset of the function, so we have - to do our own relocation. Later, when the dynamic linker actually - runs, it relocates r_brk to be the actual address of _r_debug_state(). - - The debugger interface structure also contains an enumeration which - is set to either RT_ADD or RT_DELETE prior to changing the mapping, - depending upon whether or not the library is being mapped or unmapped, - and then set to RT_CONSISTENT after the library is mapped/unmapped. -*/ - -static int -enable_break () -{ - int success = 0; - -#ifndef SVR4_SHARED_LIBS - - int j; - int in_debugger; - - /* Get link_dynamic structure */ - - j = target_read_memory (debug_base, (char *) &dynamic_copy, - sizeof (dynamic_copy)); - if (j) - { - /* unreadable */ - return (0); - } - - /* Calc address of debugger interface structure */ - - debug_addr = (CORE_ADDR) dynamic_copy.ldd; - - /* Calc address of `in_debugger' member of debugger interface structure */ - - flag_addr = debug_addr + (CORE_ADDR) ((char *) &debug_copy.ldd_in_debugger - - (char *) &debug_copy); - - /* Write a value of 1 to this member. */ - - in_debugger = 1; - write_memory (flag_addr, (char *) &in_debugger, sizeof (in_debugger)); - success = 1; - -#else /* SVR4_SHARED_LIBS */ - -#ifdef BKPT_AT_SYMBOL - - struct minimal_symbol *msymbol; - char **bkpt_namep; - CORE_ADDR bkpt_addr; - - /* Scan through the list of symbols, trying to look up the symbol and - set a breakpoint there. Terminate loop when we/if we succeed. */ - - breakpoint_addr = 0; - for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++) - { - msymbol = lookup_minimal_symbol (*bkpt_namep, symfile_objfile); - if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0)) - { - bkpt_addr = SYMBOL_VALUE_ADDRESS (msymbol); - if (target_insert_breakpoint (bkpt_addr, shadow_contents) == 0) - { - breakpoint_addr = bkpt_addr; - success = 1; - break; - } - } - } - -#else /* !BKPT_AT_SYMBOL */ - - struct symtab_and_line sal; - - /* Read the debugger interface structure directly. */ - - read_memory (debug_base, (char *) &debug_copy, sizeof (debug_copy)); - - /* Set breakpoint at the debugger interface stub routine that will - be called just prior to each mapping change and again after the - mapping change is complete. Set up the (nonexistent) handler to - deal with hitting these breakpoints. (FIXME). */ - - warning ("'%s': line %d: missing SVR4 support code", __FILE__, __LINE__); - success = 1; - -#endif /* BKPT_AT_SYMBOL */ - -#endif /* !SVR4_SHARED_LIBS */ - - return (success); -} - -/* - -GLOBAL FUNCTION - - solib_create_inferior_hook -- shared library startup support - -SYNOPSIS - - void solib_create_inferior_hook() - -DESCRIPTION - - When gdb starts up the inferior, it nurses it along (through the - shell) until it is ready to execute it's first instruction. At this - point, this function gets called via expansion of the macro - SOLIB_CREATE_INFERIOR_HOOK. - - For SunOS executables, this first instruction is typically the - one at "_start", or a similar text label, regardless of whether - the executable is statically or dynamically linked. The runtime - startup code takes care of dynamically linking in any shared - libraries, once gdb allows the inferior to continue. - - For SVR4 executables, this first instruction is either the first - instruction in the dynamic linker (for dynamically linked - executables) or the instruction at "start" for statically linked - executables. For dynamically linked executables, the system - first exec's /lib/libc.so.N, which contains the dynamic linker, - and starts it running. The dynamic linker maps in any needed - shared libraries, maps in the actual user executable, and then - jumps to "start" in the user executable. - - For both SunOS shared libraries, and SVR4 shared libraries, we - can arrange to cooperate with the dynamic linker to discover the - names of shared libraries that are dynamically linked, and the - base addresses to which they are linked. - - This function is responsible for discovering those names and - addresses, and saving sufficient information about them to allow - their symbols to be read at a later time. - -FIXME - - Between enable_break() and disable_break(), this code does not - properly handle hitting breakpoints which the user might have - set in the startup code or in the dynamic linker itself. Proper - handling will probably have to wait until the implementation is - changed to use the "breakpoint handler function" method. - - Also, what if child has exit()ed? Must exit loop somehow. - */ - -void -solib_create_inferior_hook() -{ - /* If we are using the BKPT_AT_SYMBOL code, then we don't need the base - yet. In fact, in the case of a SunOS4 executable being run on - Solaris, we can't get it yet. find_solib will get it when it needs - it. */ -#if !(defined (SVR4_SHARED_LIBS) && defined (BKPT_AT_SYMBOL)) - if ((debug_base = locate_base ()) == 0) - { - /* Can't find the symbol or the executable is statically linked. */ - return; - } -#endif - - if (!enable_break ()) - { - warning ("shared library handler failed to enable breakpoint"); - return; - } - - /* Now run the target. It will eventually hit the breakpoint, at - which point all of the libraries will have been mapped in and we - can go groveling around in the dynamic linker structures to find - out what we need to know about them. */ - - clear_proceed_status (); - stop_soon_quietly = 1; - stop_signal = TARGET_SIGNAL_0; - do - { - target_resume (-1, 0, stop_signal); - wait_for_inferior (); - } - while (stop_signal != TARGET_SIGNAL_TRAP); - stop_soon_quietly = 0; - - /* 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 - add any shared libraries that were mapped in. */ - - if (DECR_PC_AFTER_BREAK) - { - stop_pc -= DECR_PC_AFTER_BREAK; - write_register (PC_REGNUM, stop_pc); - } - - if (!disable_break ()) - { - warning ("shared library handler failed to disable breakpoint"); - } - - solib_add ((char *) 0, 0, (struct target_ops *) 0); -} - -/* - -LOCAL FUNCTION - - special_symbol_handling -- additional shared library symbol handling - -SYNOPSIS - - void special_symbol_handling (struct so_list *so) - -DESCRIPTION - - Once the symbols from a shared object have been loaded in the usual - way, we are called to do any system specific symbol handling that - is needed. - - For Suns, this consists of grunging around in the dynamic linkers - structures to find symbol definitions for "common" symbols and - adding them to the minimal symbol table for the corresponding - objfile. - -*/ - -static void -special_symbol_handling (so) -struct so_list *so; -{ -#ifndef SVR4_SHARED_LIBS - int j; - - if (debug_addr == 0) - { - /* Get link_dynamic structure */ - - j = target_read_memory (debug_base, (char *) &dynamic_copy, - sizeof (dynamic_copy)); - if (j) - { - /* unreadable */ - return; - } - - /* Calc address of debugger interface structure */ - /* FIXME, this needs work for cross-debugging of core files - (byteorder, size, alignment, etc). */ - - debug_addr = (CORE_ADDR) dynamic_copy.ldd; - } - - /* Read the debugger structure from the inferior, just to make sure - we have a current copy. */ - - j = target_read_memory (debug_addr, (char *) &debug_copy, - sizeof (debug_copy)); - if (j) - return; /* unreadable */ - - /* Get common symbol definitions for the loaded object. */ - - if (debug_copy.ldd_cp) - { - solib_add_common_symbols (debug_copy.ldd_cp, so -> objfile); - } - -#endif /* !SVR4_SHARED_LIBS */ -} - - -/* - -LOCAL FUNCTION - - sharedlibrary_command -- handle command to explicitly add library - -SYNOPSIS - - static void sharedlibrary_command (char *args, int from_tty) - -DESCRIPTION - -*/ - -static void -sharedlibrary_command (args, from_tty) -char *args; -int from_tty; -{ - dont_repeat (); - solib_add (args, from_tty, (struct target_ops *) 0); -} - -void -_initialize_solib() -{ - - add_com ("sharedlibrary", class_files, sharedlibrary_command, - "Load shared object library symbols for files matching REGEXP."); - add_info ("sharedlibrary", info_sharedlibrary_command, - "Status of loaded shared object libraries."); -} diff --git a/gnu/usr.bin/gdb/gdb/solib.h b/gnu/usr.bin/gdb/gdb/solib.h deleted file mode 100644 index ddabf74..0000000 --- a/gnu/usr.bin/gdb/gdb/solib.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Shared library declarations for GDB, the GNU Debugger. - Copyright (C) 1992 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. */ - -#ifdef __STDC__ /* Forward decl's for prototypes */ -struct target_ops; -#endif - -/* Called when we free all symtabs, to free the shared library information - as well. */ - -#define CLEAR_SOLIB clear_solib - -extern void -clear_solib PARAMS ((void)); - -/* Called to add symbols from a shared library to gdb's symbol table. */ - -#define SOLIB_ADD(filename, from_tty, targ) \ - solib_add (filename, from_tty, targ) - -extern void -solib_add PARAMS ((char *, int, struct target_ops *)); - -/* Function to be called when the inferior starts up, to discover the names - of shared libraries that are dynamically linked, the base addresses to - which they are linked, and sufficient information to read in their symbols - at a later time. */ - -#define SOLIB_CREATE_INFERIOR_HOOK(PID) solib_create_inferior_hook() - -extern void -solib_create_inferior_hook PARAMS((void)); /* solib.c */ - -/* If we can't set a breakpoint, and it's in a shared library, just - disable it. */ - -#define DISABLE_UNSETTABLE_BREAK(addr) solib_address(addr) - -extern int -solib_address PARAMS ((CORE_ADDR)); /* solib.c */ diff --git a/gnu/usr.bin/gdb/gdb/source.c b/gnu/usr.bin/gdb/gdb/source.c deleted file mode 100644 index 9dc175b..0000000 --- a/gnu/usr.bin/gdb/gdb/source.c +++ /dev/null @@ -1,1415 +0,0 @@ -/* List lines of source files for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1988, 1989, 1991 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 "defs.h" -#include "symtab.h" -#include "expression.h" -#include "language.h" -#include "command.h" -#include "gdbcmd.h" -#include "frame.h" - -#include -#include -#include -#include -#include -#include "gdbcore.h" -#include "gnuregex.h" -#include "symfile.h" -#include "objfiles.h" -#include "annotate.h" - -#ifndef DIRNAME_SEPARATOR -#define DIRNAME_SEPARATOR ':' -#endif - -/* Prototypes for local functions. */ - -static int -open_source_file PARAMS ((struct symtab *)); - -static int -get_filename_and_charpos PARAMS ((struct symtab *, char **)); - -static void -reverse_search_command PARAMS ((char *, int)); - -static void -forward_search_command PARAMS ((char *, int)); - -static void -line_info PARAMS ((char *, int)); - -static void -list_command PARAMS ((char *, int)); - -static void -ambiguous_line_spec PARAMS ((struct symtabs_and_lines *)); - -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. */ - -char *source_path; - -/* Symtab of default file for listing lines of. */ - -struct symtab *current_source_symtab; - -/* Default next line to list. */ - -int current_source_line; - -/* Default number of lines to print with commands like "list". - This is based on guessing how many long (i.e. more than chars_per_line - characters) lines there will be. To be completely correct, "list" - and friends should be rewritten to count characters and see where - things are wrapping, but that would be a fair amount of work. */ - -int lines_to_list = 10; - -/* Line number of last line printed. Default for various commands. - current_source_line is usually, but not always, the same as this. */ - -static int last_line_listed; - -/* First line number listed by last listing command. */ - -static int first_line_listed; - - -/* Set the source file default for the "list" command to be S. - - If S is NULL, and we don't have a default, find one. This - should only be called when the user actually tries to use the - default, since we produce an error if we can't find a reasonable - default. Also, since this can cause symbols to be read, doing it - before we need to would make things slower than necessary. */ - -void -select_source_symtab (s) - register struct symtab *s; -{ - struct symtabs_and_lines sals; - struct symtab_and_line sal; - struct partial_symtab *ps; - struct partial_symtab *cs_pst = 0; - struct objfile *ofp; - - if (s) - { - current_source_symtab = s; - current_source_line = 1; - return; - } - - if (current_source_symtab) - return; - - /* Make the default place to list be the function `main' - if one exists. */ - if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0, NULL)) - { - sals = decode_line_spec ("main", 1); - sal = sals.sals[0]; - free (sals.sals); - current_source_symtab = sal.symtab; - current_source_line = max (sal.line - (lines_to_list - 1), 1); - if (current_source_symtab) - return; - } - - /* All right; find the last file in the symtab list (ignoring .h's). */ - - current_source_line = 1; - - for (ofp = object_files; ofp != NULL; ofp = ofp -> next) - { - for (s = ofp -> symtabs; s; s = s->next) - { - char *name = s -> filename; - int len = strlen (name); - if (! (len > 2 && (STREQ (&name[len - 2], ".h")))) - { - current_source_symtab = s; - } - } - } - if (current_source_symtab) - return; - - /* Howabout the partial symbol tables? */ - - for (ofp = object_files; ofp != NULL; ofp = ofp -> next) - { - for (ps = ofp -> psymtabs; ps != NULL; ps = ps -> next) - { - char *name = ps -> filename; - int len = strlen (name); - if (! (len > 2 && (STREQ (&name[len - 2], ".h")))) - { - cs_pst = ps; - } - } - } - if (cs_pst) - { - if (cs_pst -> readin) - { - fatal ("Internal: select_source_symtab: readin pst found and no symtabs."); - } - else - { - current_source_symtab = PSYMTAB_TO_SYMTAB (cs_pst); - } - } - - error ("Can't find a default source file"); -} - -static void -show_directories (ignore, from_tty) - char *ignore; - int from_tty; -{ - puts_filtered ("Source directories searched: "); - puts_filtered (source_path); - puts_filtered ("\n"); -} - -/* Forget what we learned about line positions in source files, - and which directories contain them; - must check again now since files may be found in - a different directory now. */ - -void -forget_cached_source_info () -{ - register struct symtab *s; - register struct objfile *objfile; - - for (objfile = object_files; objfile != NULL; objfile = objfile -> next) - { - for (s = objfile -> symtabs; s != NULL; s = s -> next) - { - if (s -> line_charpos != NULL) - { - mfree (objfile -> md, s -> line_charpos); - s -> line_charpos = NULL; - } - if (s -> fullname != NULL) - { - mfree (objfile -> md, s -> fullname); - s -> fullname = NULL; - } - } - } -} - -void -init_source_path () -{ - char buf[20]; - - sprintf (buf, "$cdir%c$cwd", DIRNAME_SEPARATOR); - source_path = strsave (buf); - forget_cached_source_info (); -} - -/* Add zero or more directories to the front of the source path. */ - -void -directory_command (dirname, from_tty) - char *dirname; - int from_tty; -{ - dont_repeat (); - /* FIXME, this goes to "delete dir"... */ - if (dirname == 0) - { - if (query ("Reinitialize source path to empty? ", "")) - { - free (source_path); - init_source_path (); - } - } - else - mod_path (dirname, &source_path); - if (from_tty) - show_directories ((char *)0, from_tty); - forget_cached_source_info (); -} - -/* Add zero or more directories to the front of an arbitrary path. */ - -void -mod_path (dirname, which_path) - char *dirname; - char **which_path; -{ - char *old = *which_path; - int prefix = 0; - - if (dirname == 0) - return; - - dirname = strsave (dirname); - make_cleanup (free, dirname); - - do - { - char *name = dirname; - register char *p; - struct stat st; - - { - char *colon = strchr (name, DIRNAME_SEPARATOR); - char *space = strchr (name, ' '); - char *tab = strchr (name, '\t'); - if (colon == 0 && space == 0 && tab == 0) - p = dirname = name + strlen (name); - else - { - p = 0; - if (colon != 0 && (p == 0 || colon < p)) - p = colon; - if (space != 0 && (p == 0 || space < p)) - p = space; - if (tab != 0 && (p == 0 || tab < p)) - p = tab; - dirname = p + 1; - while (*dirname == DIRNAME_SEPARATOR || *dirname == ' ' || *dirname == '\t') - ++dirname; - } - } - - if (p[-1] == '/') - /* Sigh. "foo/" => "foo" */ - --p; - *p = '\0'; - - while (p[-1] == '.') - { - if (p - name == 1) - { - /* "." => getwd (). */ - name = current_directory; - goto append; - } - else if (p[-2] == '/') - { - if (p - name == 2) - { - /* "/." => "/". */ - *--p = '\0'; - goto append; - } - else - { - /* "...foo/." => "...foo". */ - p -= 2; - *p = '\0'; - continue; - } - } - else - break; - } - - if (name[0] == '~') - name = tilde_expand (name); - else if (name[0] != '/' && name[0] != '$') - name = concat (current_directory, "/", name, NULL); - else - name = savestring (name, p - name); - make_cleanup (free, name); - - /* Unless it's a variable, check existence. */ - if (name[0] != '$') { - /* These are warnings, not errors, since we don't want a - non-existent directory in a .gdbinit file to stop processing - of the .gdbinit file. - - Whether they get added to the path is more debatable. Current - answer is yes, in case the user wants to go make the directory - or whatever. If the directory continues to not exist/not be - a directory/etc, then having them in the path should be - harmless. */ - if (stat (name, &st) < 0) - { - int save_errno = errno; - fprintf_unfiltered (gdb_stderr, "Warning: "); - print_sys_errmsg (name, save_errno); - } - else if ((st.st_mode & S_IFMT) != S_IFDIR) - warning ("%s is not a directory.", name); - } - - append: - { - register unsigned int len = strlen (name); - - p = *which_path; - while (1) - { - if (!strncmp (p, name, len) - && (p[len] == '\0' || p[len] == DIRNAME_SEPARATOR)) - { - /* Found it in the search path, remove old copy */ - if (p > *which_path) - p--; /* Back over leading colon */ - if (prefix > p - *which_path) - goto skip_dup; /* Same dir twice in one cmd */ - strcpy (p, &p[len+1]); /* Copy from next \0 or : */ - } - p = strchr (p, DIRNAME_SEPARATOR); - if (p != 0) - ++p; - else - break; - } - if (p == 0) - { - char tinybuf[2]; - - tinybuf[0] = DIRNAME_SEPARATOR; - tinybuf[1] = '\0'; - - /* If we have already tacked on a name(s) in this command, be sure they stay on the front as we tack on some more. */ - if (prefix) - { - char *temp, c; - - c = old[prefix]; - old[prefix] = '\0'; - temp = concat (old, tinybuf, name, NULL); - old[prefix] = c; - *which_path = concat (temp, "", &old[prefix], NULL); - prefix = strlen (temp); - free (temp); - } - else - { - *which_path = concat (name, (old[0] ? tinybuf : old), old, NULL); - prefix = strlen (name); - } - free (old); - old = *which_path; - } - } - skip_dup: ; - } while (*dirname != '\0'); -} - - -static void -source_info (ignore, from_tty) - char *ignore; - int from_tty; -{ - register struct symtab *s = current_source_symtab; - - if (!s) - { - printf_filtered("No current source file.\n"); - return; - } - printf_filtered ("Current source file is %s\n", s->filename); - if (s->dirname) - printf_filtered ("Compilation directory is %s\n", s->dirname); - if (s->fullname) - printf_filtered ("Located in %s\n", s->fullname); - if (s->nlines) - printf_filtered ("Contains %d line%s.\n", s->nlines, - s->nlines == 1 ? "" : "s"); - - printf_filtered("Source language is %s.\n", language_str (s->language)); -} - - - -/* Open a file named STRING, searching path PATH (dir names sep by some char) - using mode MODE and protection bits PROT in the calls to open. - - If TRY_CWD_FIRST, try to open ./STRING before searching PATH. - (ie pretend the first element of PATH is "."). This also indicates - that a slash in STRING disables searching of the path (this is - so that "exec-file ./foo" or "symbol-file ./foo" insures that you - get that particular version of foo or an error message). - - If FILENAMED_OPENED is non-null, set it to a newly allocated string naming - the actual file opened (this string will always start with a "/". We - have to take special pains to avoid doubling the "/" between the directory - and the file, sigh! Emacs gets confuzzed by this when we print the - source file name!!! - - If a file is found, return the descriptor. - Otherwise, return -1, with errno set for the last name we tried to open. */ - -/* >>>> This should only allow files of certain types, - >>>> eg executable, non-directory */ -int -openp (path, try_cwd_first, string, mode, prot, filename_opened) - char *path; - int try_cwd_first; - char *string; - int mode; - int prot; - char **filename_opened; -{ - register int fd; - register char *filename; - register char *p, *p1; - register int len; - int alloclen; - - if (!path) - path = "."; - - if (try_cwd_first || string[0] == '/') - { - filename = string; - fd = open (filename, mode, prot); - if (fd >= 0 || string[0] == '/' || strchr (string, '/')) - goto done; - } - - /* ./foo => foo */ - while (string[0] == '.' && string[1] == '/') - string += 2; - - alloclen = strlen (path) + strlen (string) + 2; - filename = (char *) alloca (alloclen); - fd = -1; - for (p = path; p; p = p1 ? p1 + 1 : 0) - { - p1 = (char *) strchr (p, DIRNAME_SEPARATOR); - if (p1) - len = p1 - p; - else - len = strlen (p); - - if (len == 4 && p[0] == '$' && p[1] == 'c' - && p[2] == 'w' && p[3] == 'd') { - /* Name is $cwd -- insert current directory name instead. */ - int newlen; - - /* First, realloc the filename buffer if too short. */ - len = strlen (current_directory); - newlen = len + strlen (string) + 2; - if (newlen > alloclen) { - alloclen = newlen; - filename = (char *) alloca (alloclen); - } - strcpy (filename, current_directory); - } else { - /* Normal file name in path -- just use it. */ - strncpy (filename, p, len); - filename[len] = 0; - } - - /* Remove trailing slashes */ - while (len > 0 && filename[len-1] == '/') - filename[--len] = 0; - - strcat (filename+len, "/"); - strcat (filename, string); - - fd = open (filename, mode); - if (fd >= 0) break; - } - - done: - if (filename_opened) - if (fd < 0) - *filename_opened = (char *) 0; - else if (filename[0] == '/') - *filename_opened = savestring (filename, strlen (filename)); - else - { - /* Beware the // my son, the Emacs barfs, the botch that catch... */ - - *filename_opened = concat (current_directory, - '/' == current_directory[strlen(current_directory)-1]? "": "/", - filename, NULL); - } - - return fd; -} - -/* Open a source file given a symtab S. Returns a file descriptor - or negative number for error. */ - -static int -open_source_file (s) - struct symtab *s; -{ - char *path = source_path; - char *p; - int result; - char *fullname; - - /* Quick way out if we already know its full name */ - if (s->fullname) - { - result = open (s->fullname, O_RDONLY); - if (result >= 0) - return result; - /* Didn't work -- free old one, try again. */ - mfree (s->objfile->md, s->fullname); - s->fullname = NULL; - } - - if (s->dirname != NULL) - { - /* Replace a path entry of $cdir with the compilation directory name */ -#define cdir_len 5 - /* We cast strstr's result in case an ANSIhole has made it const, - which produces a "required warning" when assigned to a nonconst. */ - p = (char *)strstr (source_path, "$cdir"); - if (p && (p == path || p[-1] == DIRNAME_SEPARATOR) - && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0')) { - int len; - - path = (char *) - alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1); - len = p - source_path; - strncpy (path, source_path, len); /* Before $cdir */ - strcpy (path + len, s->dirname); /* new stuff */ - strcat (path + len, source_path + len + cdir_len); /* After $cdir */ - } - } - - result = openp (path, 0, s->filename, O_RDONLY, 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); - } - if (result >= 0) - { - fullname = s->fullname; - s->fullname = mstrsave (s->objfile->md, s->fullname); - free (fullname); - } - return result; -} - - -/* Create and initialize the table S->line_charpos that records - the positions of the lines in the source file, which is assumed - to be open on descriptor DESC. - All set S->nlines to the number of such lines. */ - -static void -find_source_lines (s, desc) - struct symtab *s; - int desc; -{ - struct stat st; - register char *data, *p, *end; - int nlines = 0; - int lines_allocated = 1000; - int *line_charpos; - long exec_mtime; - int size; - - line_charpos = (int *) xmmalloc (s -> objfile -> md, - lines_allocated * sizeof (int)); - if (fstat (desc, &st) < 0) - perror_with_name (s->filename); - - if (exec_bfd) - { - 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"); - } - -#ifdef LSEEK_NOT_LINEAR - { - char c; - - /* Have to read it byte by byte to find out where the chars live */ - - line_charpos[0] = tell(desc); - nlines = 1; - while (myread(desc, &c, 1)>0) - { - if (c == '\n') - { - if (nlines == lines_allocated) - { - lines_allocated *= 2; - line_charpos = - (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos, - sizeof (int) * lines_allocated); - } - line_charpos[nlines++] = tell(desc); - } - } - } -#else /* lseek linear. */ - { - struct cleanup *old_cleanups; - - /* st_size might be a large type, but we only support source files whose - size fits in an int. */ - size = (int) st.st_size; - - /* Use malloc, not alloca, because this may be pretty large, and we may - run into various kinds of limits on stack size. */ - data = (char *) xmalloc (size); - old_cleanups = make_cleanup (free, data); - - if (myread (desc, data, size) < 0) - perror_with_name (s->filename); - end = data + size; - p = data; - line_charpos[0] = 0; - nlines = 1; - while (p != end) - { - if (*p++ == '\n' - /* A newline at the end does not start a new line. */ - && p != end) - { - if (nlines == lines_allocated) - { - lines_allocated *= 2; - line_charpos = - (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos, - sizeof (int) * lines_allocated); - } - line_charpos[nlines++] = p - data; - } - } - do_cleanups (old_cleanups); - } -#endif /* lseek linear. */ - s->nlines = nlines; - s->line_charpos = - (int *) xmrealloc (s -> objfile -> md, (char *) line_charpos, - nlines * sizeof (int)); - -} - -/* Return the character position of a line LINE in symtab S. - Return 0 if anything is invalid. */ - -#if 0 /* Currently unused */ - -int -source_line_charpos (s, line) - struct symtab *s; - int line; -{ - if (!s) return 0; - if (!s->line_charpos || line <= 0) return 0; - if (line > s->nlines) - line = s->nlines; - return s->line_charpos[line - 1]; -} - -/* Return the line number of character position POS in symtab S. */ - -int -source_charpos_line (s, chr) - register struct symtab *s; - register int chr; -{ - register int line = 0; - register int *lnp; - - if (s == 0 || s->line_charpos == 0) return 0; - lnp = s->line_charpos; - /* Files are usually short, so sequential search is Ok */ - while (line < s->nlines && *lnp <= chr) - { - line++; - lnp++; - } - if (line >= s->nlines) - line = s->nlines; - return line; -} - -#endif /* 0 */ - - -/* Get full pathname and line number positions for a symtab. - Return nonzero if line numbers may have changed. - Set *FULLNAME to actual name of the file as found by `openp', - or to 0 if the file is not found. */ - -static int -get_filename_and_charpos (s, fullname) - struct symtab *s; - char **fullname; -{ - register int desc, linenums_changed = 0; - - desc = open_source_file (s); - if (desc < 0) - { - if (fullname) - *fullname = NULL; - return 0; - } - if (fullname) - *fullname = s->fullname; - if (s->line_charpos == 0) linenums_changed = 1; - if (linenums_changed) find_source_lines (s, desc); - close (desc); - return linenums_changed; -} - -/* Print text describing the full name of the source file S - and the line number LINE and its corresponding character position. - The text starts with two Ctrl-z so that the Emacs-GDB interface - can easily find it. - - MID_STATEMENT is nonzero if the PC is not at the beginning of that line. - - Return 1 if successful, 0 if could not find the file. */ - -int -identify_source_line (s, line, mid_statement, pc) - struct symtab *s; - int line; - int mid_statement; - CORE_ADDR pc; -{ - if (s->line_charpos == 0) - get_filename_and_charpos (s, (char **)NULL); - if (s->fullname == 0) - return 0; - if (line > s->nlines) - /* Don't index off the end of the line_charpos array. */ - return 0; - annotate_source (s->fullname, line, s->line_charpos[line - 1], - mid_statement, pc); - - current_source_line = line; - first_line_listed = line; - last_line_listed = line; - 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. */ - -void -print_source_lines (s, line, stopline, noerror) - struct symtab *s; - int line, stopline; - int noerror; -{ - register int c; - register int desc; - register FILE *stream; - int nlines = stopline - line; - - /* Regardless of whether we can open the file, set current_source_symtab. */ - current_source_symtab = s; - current_source_line = line; - first_line_listed = line; - - desc = open_source_file (s); - if (desc < 0) - { - if (! noerror) { - char *name = alloca (strlen (s->filename) + 100); - sprintf (name, "%s:%d", s->filename, line); - print_sys_errmsg (name, errno); - } - return; - } - - if (s->line_charpos == 0) - find_source_lines (s, desc); - - if (line < 1 || line > s->nlines) - { - close (desc); - error ("Line number %d out of range; %s has %d lines.", - line, s->filename, s->nlines); - } - - if (lseek (desc, s->line_charpos[line - 1], 0) < 0) - { - close (desc); - perror_with_name (s->filename); - } - - stream = fdopen (desc, FOPEN_RT); - clearerr (stream); - - while (nlines-- > 0) - { - c = fgetc (stream); - if (c == EOF) break; - last_line_listed = current_source_line; - printf_filtered ("%d\t", current_source_line++); - do - { - if (c < 040 && c != '\t' && c != '\n' && c != '\r') - printf_filtered ("^%c", c + 0100); - else if (c == 0177) - printf_filtered ("^?"); - else - printf_filtered ("%c", c); - } while (c != '\n' && (c = fgetc (stream)) >= 0); - } - - fclose (stream); -} - - - -/* - C++ - Print a list of files and line numbers which a user may choose from - in order to list a function which was specified ambiguously - (as with `list classname::overloadedfuncname', for example). - The vector in SALS provides the filenames and line numbers. - */ -static void -ambiguous_line_spec (sals) - struct symtabs_and_lines *sals; -{ - int i; - - for (i = 0; i < sals->nelts; ++i) - printf_filtered("file: \"%s\", line number: %d\n", - sals->sals[i].symtab->filename, sals->sals[i].line); -} - - -static void -list_command (arg, from_tty) - char *arg; - int from_tty; -{ - struct symtabs_and_lines sals, sals_end; - struct symtab_and_line sal, sal_end; - struct symbol *sym; - char *arg1; - int no_end = 1; - int dummy_end = 0; - int dummy_beg = 0; - int linenum_beg = 0; - char *p; - - if (!have_full_symbols () && !have_partial_symbols()) - error ("No symbol table is loaded. Use the \"file\" command."); - - /* Pull in a current source symtab if necessary */ - if (current_source_symtab == 0 && - (arg == 0 || arg[0] == '+' || arg[0] == '-')) - select_source_symtab (0); - - /* "l" or "l +" lists next ten lines. */ - - if (arg == 0 || STREQ (arg, "+")) - { - if (current_source_symtab == 0) - error ("No default source file yet. Do \"help list\"."); - print_source_lines (current_source_symtab, current_source_line, - current_source_line + lines_to_list, 0); - return; - } - - /* "l -" lists previous ten lines, the ones before the ten just listed. */ - if (STREQ (arg, "-")) - { - if (current_source_symtab == 0) - error ("No default source file yet. Do \"help list\"."); - print_source_lines (current_source_symtab, - max (first_line_listed - lines_to_list, 1), - first_line_listed, 0); - return; - } - - /* Now if there is only one argument, decode it in SAL - and set NO_END. - If there are two arguments, decode them in SAL and SAL_END - and clear NO_END; however, if one of the arguments is blank, - set DUMMY_BEG or DUMMY_END to record that fact. */ - - arg1 = arg; - if (*arg1 == ',') - dummy_beg = 1; - else - { - sals = decode_line_1 (&arg1, 0, 0, 0, 0); - - if (! sals.nelts) return; /* C++ */ - if (sals.nelts > 1) - { - ambiguous_line_spec (&sals); - free (sals.sals); - return; - } - - sal = sals.sals[0]; - free (sals.sals); - } - - /* Record whether the BEG arg is all digits. */ - - for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++); - linenum_beg = (p == arg1); - - while (*arg1 == ' ' || *arg1 == '\t') - arg1++; - if (*arg1 == ',') - { - no_end = 0; - arg1++; - while (*arg1 == ' ' || *arg1 == '\t') - arg1++; - if (*arg1 == 0) - dummy_end = 1; - else - { - if (dummy_beg) - sals_end = decode_line_1 (&arg1, 0, 0, 0, 0); - else - sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0); - if (sals_end.nelts == 0) - return; - if (sals_end.nelts > 1) - { - ambiguous_line_spec (&sals_end); - free (sals_end.sals); - return; - } - sal_end = sals_end.sals[0]; - free (sals_end.sals); - } - } - - if (*arg1) - error ("Junk at end of line specification."); - - if (!no_end && !dummy_beg && !dummy_end - && sal.symtab != sal_end.symtab) - error ("Specified start and end are in different files."); - if (dummy_beg && dummy_end) - error ("Two empty args do not say what lines to list."); - - /* if line was specified by address, - first print exactly which line, and which file. - In this case, sal.symtab == 0 means address is outside - of all known source files, not that user failed to give a filename. */ - if (*arg == '*') - { - if (sal.symtab == 0) - /* FIXME-32x64--assumes sal.pc fits in long. */ - error ("No source file for address %s.", - local_hex_string((unsigned long) sal.pc)); - sym = find_pc_function (sal.pc); - if (sym) - { - print_address_numeric (sal.pc, 1, gdb_stdout); - printf_filtered (" is in "); - fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout); - printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line); - } - else - { - print_address_numeric (sal.pc, 1, gdb_stdout); - printf_filtered (" is at %s:%d.\n", - sal.symtab->filename, sal.line); - } - } - - /* If line was not specified by just a line number, - and it does not imply a symtab, it must be an undebuggable symbol - which means no source code. */ - - if (! linenum_beg && sal.symtab == 0) - error ("No line number known for %s.", arg); - - /* If this command is repeated with RET, - turn it into the no-arg variant. */ - - if (from_tty) - *arg = 0; - - if (dummy_beg && sal_end.symtab == 0) - error ("No default source file yet. Do \"help list\"."); - if (dummy_beg) - print_source_lines (sal_end.symtab, - max (sal_end.line - (lines_to_list - 1), 1), - sal_end.line + 1, 0); - else if (sal.symtab == 0) - error ("No default source file yet. Do \"help list\"."); - else if (no_end) - print_source_lines (sal.symtab, - max (sal.line - (lines_to_list / 2), 1), - sal.line + (lines_to_list / 2), 0); - else - print_source_lines (sal.symtab, sal.line, - (dummy_end - ? sal.line + lines_to_list - : sal_end.line + 1), - 0); -} - -/* Print info on range of pc's in a specified line. */ - -static void -line_info (arg, from_tty) - char *arg; - int from_tty; -{ - struct symtabs_and_lines sals; - struct symtab_and_line sal; - CORE_ADDR start_pc, end_pc; - int i; - - if (arg == 0) - { - sal.symtab = current_source_symtab; - sal.line = last_line_listed; - sals.nelts = 1; - sals.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - sals.sals[0] = sal; - } - else - { - sals = decode_line_spec_1 (arg, 0); - - dont_repeat (); - } - - /* C++ More than one line may have been specified, as when the user - specifies an overloaded function name. Print info on them all. */ - for (i = 0; i < sals.nelts; i++) - { - sal = sals.sals[i]; - - if (sal.symtab == 0) - { - printf_filtered ("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); - } - else - printf_filtered ("."); - printf_filtered ("\n"); - } - 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"); - } - else - { - printf_filtered ("Line %d of \"%s\"", - sal.line, sal.symtab->filename); - wrap_here (" "); - printf_filtered (" starts at address "); - print_address (start_pc, gdb_stdout); - wrap_here (" "); - printf_filtered (" and ends at "); - print_address (end_pc, gdb_stdout); - printf_filtered (".\n"); - } - - /* x/i should display this line's code. */ - set_next_address (start_pc); - - /* Repeating "info line" should do the following line. */ - last_line_listed = sal.line + 1; - - /* If this is the only line, show the source code. If it could - not find the file, don't do anything special. */ - if (annotation_level && sals.nelts == 1) - identify_source_line (sal.symtab, sal.line, 0, start_pc); - } - 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? */ - printf_filtered ("Line number %d is out of range for \"%s\".\n", - sal.line, sal.symtab->filename); - } - free (sals.sals); -} - -/* Commands to search the source file for a regexp. */ - -/* ARGSUSED */ -static void -forward_search_command (regex, from_tty) - char *regex; - int from_tty; -{ - register int c; - register int desc; - register FILE *stream; - int line = last_line_listed + 1; - char *msg; - - msg = (char *) re_comp (regex); - if (msg) - error (msg); - - 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); - - if (current_source_symtab->line_charpos == 0) - find_source_lines (current_source_symtab, desc); - - if (line < 1 || line > current_source_symtab->nlines) - { - close (desc); - error ("Expression not found"); - } - - if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) - { - close (desc); - perror_with_name (current_source_symtab->filename); - } - - stream = fdopen (desc, FOPEN_RT); - clearerr (stream); - while (1) { -/* FIXME!!! We walk right off the end of buf if we get a long line!!! */ - char buf[4096]; /* Should be reasonable??? */ - register char *p = buf; - - c = getc (stream); - if (c == EOF) - break; - do { - *p++ = c; - } while (c != '\n' && (c = getc (stream)) >= 0); - - /* we now have a source line in buf, null terminate and match */ - *p = 0; - if (re_exec (buf) > 0) - { - /* Match! */ - fclose (stream); - print_source_lines (current_source_symtab, - line, line+1, 0); - current_source_line = max (line - lines_to_list / 2, 1); - return; - } - line++; - } - - printf_filtered ("Expression not found\n"); - fclose (stream); -} - -/* ARGSUSED */ -static void -reverse_search_command (regex, from_tty) - char *regex; - int from_tty; -{ - register int c; - register int desc; - register FILE *stream; - int line = last_line_listed - 1; - char *msg; - - msg = (char *) re_comp (regex); - if (msg) - error (msg); - - 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); - - if (current_source_symtab->line_charpos == 0) - find_source_lines (current_source_symtab, desc); - - if (line < 1 || line > current_source_symtab->nlines) - { - close (desc); - error ("Expression not found"); - } - - if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) - { - close (desc); - perror_with_name (current_source_symtab->filename); - } - - stream = fdopen (desc, FOPEN_RT); - clearerr (stream); - while (line > 1) - { -/* FIXME!!! We walk right off the end of buf if we get a long line!!! */ - char buf[4096]; /* Should be reasonable??? */ - register char *p = buf; - - c = getc (stream); - if (c == EOF) - break; - do { - *p++ = c; - } while (c != '\n' && (c = getc (stream)) >= 0); - - /* We now have a source line in buf; null terminate and match. */ - *p = 0; - if (re_exec (buf) > 0) - { - /* Match! */ - fclose (stream); - print_source_lines (current_source_symtab, - line, line+1, 0); - current_source_line = max (line - lines_to_list / 2, 1); - return; - } - line--; - if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0) - { - fclose (stream); - perror_with_name (current_source_symtab->filename); - } - } - - printf_filtered ("Expression not found\n"); - fclose (stream); - return; -} - -void -_initialize_source () -{ - struct cmd_list_element *c; - current_source_symtab = 0; - init_source_path (); - - /* The intention is to use POSIX Basic Regular Expressions. - Always use the GNU regex routine for consistency across all hosts. - Our current GNU regex.c does not have all the POSIX features, so this is - just an approximation. */ - re_set_syntax (RE_SYNTAX_GREP); - - c = add_cmd ("directory", class_files, directory_command, - "Add directory DIR to beginning of search path for source files.\n\ -Forget cached info on source file locations and line positions.\n\ -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); - c->completer = filename_completer; - - add_cmd ("directories", 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.", - &showlist); - - add_info ("source", source_info, - "Information about the current source file."); - - add_info ("line", line_info, - "Core addresses of the code for a source line.\n\ -Line can be specified as\n\ - LINENUM, to list around that line in current file,\n\ - FILE:LINENUM, to list around that line in that file,\n\ - FUNCTION, to list around beginning of that function,\n\ - FILE:FUNCTION, to distinguish among like-named static functions.\n\ -Default is to describe the last source line that was listed.\n\n\ -This sets the default address for \"x\" to the line's first instruction\n\ -so that \"x/i\" suffices to start examining the machine code.\n\ -The address is also stored as the value of \"$_\"."); - - add_com ("forward-search", class_files, forward_search_command, - "Search for regular expression (see regex(3)) from last line listed."); - add_com_alias ("search", "forward-search", class_files, 0); - - add_com ("reverse-search", class_files, reverse_search_command, - "Search backward for regular expression (see regex(3)) from last line listed."); - - add_com ("list", class_files, list_command, - "List specified function or line.\n\ -With no argument, lists ten more lines after or around previous listing.\n\ -\"list -\" lists the ten lines before a previous ten-line listing.\n\ -One argument specifies a line, and ten lines are listed around that line.\n\ -Two arguments with comma between specify starting and ending lines to list.\n\ -Lines can be specified in these ways:\n\ - LINENUM, to list around that line in current file,\n\ - FILE:LINENUM, to list around that line in that file,\n\ - FUNCTION, to list around beginning of that function,\n\ - FILE:FUNCTION, to distinguish among like-named static functions.\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."); - add_com_alias ("l", "list", class_files, 1); - - add_show_from_set - (add_set_cmd ("listsize", class_support, var_uinteger, - (char *)&lines_to_list, - "Set number of source lines gdb will list by default.", - &setlist), - &showlist); -} diff --git a/gnu/usr.bin/gdb/gdb/stabsread.c b/gnu/usr.bin/gdb/gdb/stabsread.c deleted file mode 100644 index 7e4d32f..0000000 --- a/gnu/usr.bin/gdb/gdb/stabsread.c +++ /dev/null @@ -1,3948 +0,0 @@ -/* Support routines for decoding "stabs" debugging information format. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 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. */ - -/* Support routines for reading and decoding debugging information in - the "stabs" format. This format is used with many systems that use - the a.out object file format, as well as some systems that use - COFF or ELF where the stabs data is placed in a special section. - Avoid placing any object file format specific code in this file. */ - -#include "defs.h" -#include -#include "bfd.h" -#include "obstack.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "symfile.h" -#include "objfiles.h" -#include "aout/stab_gnu.h" /* We always use GNU stabs, not native */ -#include "libaout.h" -#include "aout/aout64.h" -#include "gdb-stabs.h" -#include "buildsym.h" -#include "complaints.h" -#include "demangle.h" - -#include - -/* Ask stabsread.h to define the vars it normally declares `extern'. */ -#define EXTERN /**/ -#include "stabsread.h" /* Our own declarations */ -#undef EXTERN - -/* The routines that read and process a complete stabs 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. - This is part of some reorganization of low level C++ support and is - expected to eventually go away... (FIXME) */ - -struct field_info -{ - struct nextfield - { - struct nextfield *next; - - /* This is the raw visibility from the stab. It is not checked - for being one of the visibilities we recognize, so code which - examines this field better be able to deal. */ - int visibility; - - struct field field; - } *list; - struct next_fnfieldlist - { - struct next_fnfieldlist *next; - struct fn_fieldlist fn_fieldlist; - } *fnlist; -}; - -static struct type * -dbx_alloc_type PARAMS ((int [2], struct objfile *)); - -static long read_huge_number PARAMS ((char **, int, int *)); - -static struct type *error_type PARAMS ((char **)); - -static void -patch_block_stabs PARAMS ((struct pending *, struct pending_stabs *, - struct objfile *)); - -static void -fix_common_block PARAMS ((struct symbol *, int)); - -static int -read_type_number PARAMS ((char **, int *)); - -static struct type * -read_range_type PARAMS ((char **, int [2], struct objfile *)); - -static struct type * -read_sun_builtin_type PARAMS ((char **, int [2], struct objfile *)); - -static struct type * -read_sun_floating_type PARAMS ((char **, int [2], struct objfile *)); - -static struct type * -read_enum_type PARAMS ((char **, struct type *, struct objfile *)); - -static struct type * -rs6000_builtin_type PARAMS ((int)); - -static int -read_member_functions PARAMS ((struct field_info *, char **, struct type *, - struct objfile *)); - -static int -read_struct_fields PARAMS ((struct field_info *, char **, struct type *, - struct objfile *)); - -static int -read_baseclasses PARAMS ((struct field_info *, char **, struct type *, - struct objfile *)); - -static int -read_tilde_fields PARAMS ((struct field_info *, char **, struct type *, - struct objfile *)); - -static int -attach_fn_fields_to_type PARAMS ((struct field_info *, struct type *)); - -static int -attach_fields_to_type PARAMS ((struct field_info *, struct type *, - struct objfile *)); - -static struct type * -read_struct_type PARAMS ((char **, struct type *, struct objfile *)); - -static struct type * -read_array_type PARAMS ((char **, struct type *, struct objfile *)); - -static struct type ** -read_args PARAMS ((char **, int, struct objfile *)); - -static int -read_cpp_abbrev PARAMS ((struct field_info *, char **, struct type *, - struct objfile *)); - -static const char vptr_name[] = { '_','v','p','t','r',CPLUS_MARKER,'\0' }; -static const char vb_name[] = { '_','v','b',CPLUS_MARKER,'\0' }; - -/* Define this as 1 if a pcc declaration of a char or short argument - gives the correct address. Otherwise assume pcc gives the - address of the corresponding int, which is not the same on a - big-endian machine. */ - -#ifndef BELIEVE_PCC_PROMOTION -#define BELIEVE_PCC_PROMOTION 0 -#endif - -struct complaint invalid_cpp_abbrev_complaint = - {"invalid C++ abbreviation `%s'", 0, 0}; - -struct complaint invalid_cpp_type_complaint = - {"C++ abbreviated type name unknown at symtab pos %d", 0, 0}; - -struct complaint member_fn_complaint = - {"member function type missing, got '%c'", 0, 0}; - -struct complaint const_vol_complaint = - {"const/volatile indicator missing, got '%c'", 0, 0}; - -struct complaint error_type_complaint = - {"debug info mismatch between compiler and debugger", 0, 0}; - -struct complaint invalid_member_complaint = - {"invalid (minimal) member type data format at symtab pos %d.", 0, 0}; - -struct complaint range_type_base_complaint = - {"base type %d of range type is not defined", 0, 0}; - -struct complaint reg_value_complaint = - {"register number too large in symbol %s", 0, 0}; - -struct complaint vtbl_notfound_complaint = - {"virtual function table pointer not found when defining class `%s'", 0, 0}; - -struct complaint unrecognized_cplus_name_complaint = - {"Unknown C++ symbol name `%s'", 0, 0}; - -struct complaint rs6000_builtin_complaint = - {"Unknown builtin type %d", 0, 0}; - -struct complaint stabs_general_complaint = - {"%s", 0, 0}; - -/* Make a list of forward references which haven't been defined. */ - -static struct type **undef_types; -static int undef_types_allocated; -static int undef_types_length; - -/* Check for and handle cretinous stabs symbol name continuation! */ -#define STABS_CONTINUE(pp) \ - do { \ - if (**(pp) == '\\' || (**(pp) == '?' && (*(pp))[1] == '\0')) \ - *(pp) = next_symbol_text (); \ - } while (0) - -/* FIXME: These probably should be our own types (like rs6000_builtin_type - has its own types) rather than builtin_type_*. */ -static struct type **os9k_type_vector[] = { - 0, - &builtin_type_int, - &builtin_type_char, - &builtin_type_long, - &builtin_type_short, - &builtin_type_unsigned_char, - &builtin_type_unsigned_short, - &builtin_type_unsigned_long, - &builtin_type_unsigned_int, - &builtin_type_float, - &builtin_type_double, - &builtin_type_void, - &builtin_type_long_double -}; - -static void os9k_init_type_vector PARAMS ((struct type **)); - -static void -os9k_init_type_vector(tv) - struct type **tv; -{ - int i; - for (i=0; i= n_this_object_header_files) - { - static struct complaint msg = {"\ -Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.", - 0, 0}; - complain (&msg, filenum, index, symnum); - goto error_return; - } - - if (filenum == 0) - { - if (index < 0) - { - /* Caller wants address of address of type. We think - that negative (rs6k builtin) types will never appear as - "lvalues", (nor should they), so we stuff the real type - pointer into a temp, and return its address. If referenced, - this will do the right thing. */ - static struct type *temp_type; - - temp_type = rs6000_builtin_type(index); - return &temp_type; - } - - /* Type is defined outside of header files. - Find it in this object file's type vector. */ - if (index >= type_vector_length) - { - old_len = type_vector_length; - if (old_len == 0) - { - type_vector_length = INITIAL_TYPE_VECTOR_LENGTH; - type_vector = (struct type **) - malloc (type_vector_length * sizeof (struct type *)); - } - while (index >= type_vector_length) - { - type_vector_length *= 2; - } - type_vector = (struct type **) - xrealloc ((char *) type_vector, - (type_vector_length * sizeof (struct type *))); - memset (&type_vector[old_len], 0, - (type_vector_length - old_len) * sizeof (struct type *)); - - if (os9k_stabs) - /* Deal with OS9000 fundamental types. */ - os9k_init_type_vector (type_vector); - } - return (&type_vector[index]); - } - else - { - real_filenum = this_object_header_files[filenum]; - - if (real_filenum >= n_header_files) - { - struct type *temp_type; - struct type **temp_type_p; - - warning ("GDB internal error: bad real_filenum"); - - error_return: - temp_type = init_type (TYPE_CODE_ERROR, 0, 0, NULL, NULL); - temp_type_p = (struct type **) xmalloc (sizeof (struct type *)); - *temp_type_p = temp_type; - return temp_type_p; - } - - f = &header_files[real_filenum]; - - f_orig_length = f->length; - if (index >= f_orig_length) - { - while (index >= f->length) - { - f->length *= 2; - } - f->vector = (struct type **) - xrealloc ((char *) f->vector, f->length * sizeof (struct type *)); - memset (&f->vector[f_orig_length], 0, - (f->length - f_orig_length) * sizeof (struct type *)); - } - return (&f->vector[index]); - } -} - -/* Make sure there is a type allocated for type numbers TYPENUMS - and return the type object. - This can create an empty (zeroed) type object. - TYPENUMS may be (-1, -1) to return a new type object that is not - put into the type vector, and so may not be referred to by number. */ - -static struct type * -dbx_alloc_type (typenums, objfile) - int typenums[2]; - struct objfile *objfile; -{ - register struct type **type_addr; - - if (typenums[0] == -1) - { - return (alloc_type (objfile)); - } - - type_addr = dbx_lookup_type (typenums); - - /* If we are referring to a type not known at all yet, - allocate an empty type for it. - We will fill it in later if we find out how. */ - if (*type_addr == 0) - { - *type_addr = alloc_type (objfile); - } - - return (*type_addr); -} - -/* for all the stabs in a given stab vector, build appropriate types - and fix their symbols in given symbol vector. */ - -static void -patch_block_stabs (symbols, stabs, objfile) - struct pending *symbols; - struct pending_stabs *stabs; - struct objfile *objfile; -{ - int ii; - char *name; - char *pp; - struct symbol *sym; - - if (stabs) - { - - /* for all the stab entries, find their corresponding symbols and - patch their types! */ - - for (ii = 0; ii < stabs->count; ++ii) - { - name = stabs->stab[ii]; - pp = (char*) strchr (name, ':'); - while (pp[1] == ':') - { - pp += 2; - pp = (char *)strchr(pp, ':'); - } - sym = find_symbol_in_list (symbols, name, pp-name); - if (!sym) - { - /* FIXME-maybe: it would be nice if we noticed whether - the variable was defined *anywhere*, not just whether - it is defined in this compilation unit. But neither - xlc or GCC seem to need such a definition, and until - we do psymtabs (so that the minimal symbols from all - compilation units are available now), I'm not sure - how to get the information. */ - - /* On xcoff, if a global is defined and never referenced, - ld will remove it from the executable. There is then - a N_GSYM stab for it, but no regular (C_EXT) symbol. */ - sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - - memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; - SYMBOL_NAME (sym) = - obstack_copy0 (&objfile->symbol_obstack, name, pp - name); - pp += 2; - if (*(pp-1) == 'F' || *(pp-1) == 'f') - { - /* I don't think the linker does this with functions, - so as far as I know this is never executed. - But it doesn't hurt to check. */ - SYMBOL_TYPE (sym) = - lookup_function_type (read_type (&pp, objfile)); - } - else - { - SYMBOL_TYPE (sym) = read_type (&pp, objfile); - } - add_symbol_to_list (sym, &global_symbols); - } - else - { - pp += 2; - if (*(pp-1) == 'F' || *(pp-1) == 'f') - { - SYMBOL_TYPE (sym) = - lookup_function_type (read_type (&pp, objfile)); - } - else - { - SYMBOL_TYPE (sym) = read_type (&pp, objfile); - } - } - } - } -} - - -/* Read a number by which a type is referred to in dbx data, - or perhaps read a pair (FILENUM, TYPENUM) in parentheses. - Just a single number N is equivalent to (0,N). - Return the two numbers by storing them in the vector TYPENUMS. - TYPENUMS will then be used as an argument to dbx_lookup_type. - - Returns 0 for success, -1 for error. */ - -static int -read_type_number (pp, typenums) - register char **pp; - register int *typenums; -{ - int nbits; - if (**pp == '(') - { - (*pp)++; - typenums[0] = read_huge_number (pp, ',', &nbits); - if (nbits != 0) return -1; - typenums[1] = read_huge_number (pp, ')', &nbits); - if (nbits != 0) return -1; - } - else - { - typenums[0] = 0; - typenums[1] = read_huge_number (pp, 0, &nbits); - if (nbits != 0) return -1; - } - return 0; -} - - -/* To handle GNU C++ typename abbreviation, we need to be able to - fill in a type's name as soon as space for that type is allocated. - `type_synonym_name' is the name of the type being allocated. - It is cleared as soon as it is used (lest all allocated types - get this name). */ - -static char *type_synonym_name; - -#if !defined (REG_STRUCT_HAS_ADDR) -#define REG_STRUCT_HAS_ADDR(gcc_p,type) 0 -#endif - -/* ARGSUSED */ -struct symbol * -define_symbol (valu, string, desc, type, objfile) - CORE_ADDR valu; - char *string; - int desc; - int type; - struct objfile *objfile; -{ - register struct symbol *sym; - char *p = (char *) strchr (string, ':'); - int deftype; - int synonym = 0; - register int i; - - /* We would like to eliminate nameless symbols, but keep their types. - E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer - to type 2, but, should not create a symbol to address that type. Since - the symbol will be nameless, there is no way any user can refer to it. */ - - int nameless; - - /* Ignore syms with empty names. */ - if (string[0] == 0) - return 0; - - /* Ignore old-style symbols from cc -go */ - if (p == 0) - return 0; - - while (p[1] == ':') - { - p += 2; - p = strchr(p, ':'); - } - - /* If a nameless stab entry, all we need is the type, not the symbol. - e.g. ":t10=*2" or a nameless enum like " :T16=ered:0,green:1,blue:2,;" */ - nameless = (p == string || ((string[0] == ' ') && (string[1] == ':'))); - - sym = (struct symbol *) - obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - - switch (type & N_TYPE) - { - case N_TEXT: - SYMBOL_SECTION(sym) = SECT_OFF_TEXT; - break; - case N_DATA: - SYMBOL_SECTION(sym) = SECT_OFF_DATA; - break; - case N_BSS: - SYMBOL_SECTION(sym) = SECT_OFF_BSS; - break; - } - - if (processing_gcc_compilation) - { - /* GCC 2.x puts the line number in desc. SunOS apparently puts in the - number of bytes occupied by a type or object, which we ignore. */ - SYMBOL_LINE(sym) = desc; - } - else - { - SYMBOL_LINE(sym) = 0; /* unknown */ - } - - if (string[0] == CPLUS_MARKER) - { - /* Special GNU C++ names. */ - switch (string[1]) - { - case 't': - SYMBOL_NAME (sym) = obsavestring ("this", strlen ("this"), - &objfile -> symbol_obstack); - break; - - case 'v': /* $vtbl_ptr_type */ - /* Was: SYMBOL_NAME (sym) = "vptr"; */ - goto normal; - - case 'e': - SYMBOL_NAME (sym) = obsavestring ("eh_throw", strlen ("eh_throw"), - &objfile -> symbol_obstack); - break; - - case '_': - /* This was an anonymous type that was never fixed up. */ - goto normal; - - default: - complain (&unrecognized_cplus_name_complaint, string); - goto normal; /* Do *something* with it */ - } - } - else - { - normal: - SYMBOL_LANGUAGE (sym) = current_subfile -> language; - SYMBOL_NAME (sym) = (char *) - obstack_alloc (&objfile -> symbol_obstack, ((p - string) + 1)); - /* Open-coded memcpy--saves function call time. */ - /* FIXME: Does it really? Try replacing with simple strcpy and - try it on an executable with a large symbol table. */ - /* FIXME: considering that gcc can open code memcpy anyway, I - doubt it. xoxorich. */ - { - register char *p1 = string; - register char *p2 = SYMBOL_NAME (sym); - while (p1 != p) - { - *p2++ = *p1++; - } - *p2++ = '\0'; - } - - /* 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_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); - } - p++; - - /* Determine the type of name being defined. */ -#if 0 - /* Getting GDB to correctly skip the symbol on an undefined symbol - descriptor and not ever dump core is a very dodgy proposition if - we do things this way. I say the acorn RISC machine can just - fix their compiler. */ - /* The Acorn RISC machine's compiler can put out locals that don't - start with "234=" or "(3,4)=", so assume anything other than the - deftypes we know how to handle is a local. */ - if (!strchr ("cfFGpPrStTvVXCR", *p)) -#else - if (isdigit (*p) || *p == '(' || *p == '-') -#endif - deftype = 'l'; - else - deftype = *p++; - - switch (deftype) - { - case 'c': - /* c is a special case, not followed by a type-number. - SYMBOL:c=iVALUE for an integer constant symbol. - SYMBOL:c=rVALUE for a floating constant symbol. - SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol. - e.g. "b:c=e6,0" for "const b = blob1" - (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ - if (*p != '=') - { - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_TYPE (sym) = error_type (&p); - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &file_symbols); - return sym; - } - ++p; - switch (*p++) - { - case 'r': - { - double d = atof (p); - char *dbl_valu; - - /* FIXME-if-picky-about-floating-accuracy: Should be using - target arithmetic to get the value. real.c in GCC - probably has the necessary code. */ - - /* FIXME: lookup_fundamental_type is a hack. We should be - creating a type especially for the type of float constants. - Problem is, what type should it be? - - Also, what should the name of this type be? Should we - be using 'S' constants (see stabs.texinfo) instead? */ - - SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile, - FT_DBL_PREC_FLOAT); - dbl_valu = (char *) - obstack_alloc (&objfile -> symbol_obstack, - TYPE_LENGTH (SYMBOL_TYPE (sym))); - store_floating (dbl_valu, TYPE_LENGTH (SYMBOL_TYPE (sym)), d); - SYMBOL_VALUE_BYTES (sym) = dbl_valu; - SYMBOL_CLASS (sym) = LOC_CONST_BYTES; - } - break; - case 'i': - { - /* Defining integer constants this way is kind of silly, - since 'e' constants allows the compiler to give not - only the value, but the type as well. C has at least - int, long, unsigned int, and long long as constant - types; other languages probably should have at least - unsigned as well as signed constants. */ - - /* We just need one int constant type for all objfiles. - It doesn't depend on languages or anything (arguably its - name should be a language-specific name for a type of - that size, but I'm inclined to say that if the compiler - wants a nice name for the type, it can use 'e'). */ - static struct type *int_const_type; - - /* Yes, this is as long as a *host* int. That is because we - use atoi. */ - if (int_const_type == NULL) - int_const_type = - init_type (TYPE_CODE_INT, - sizeof (int) * HOST_CHAR_BIT / TARGET_CHAR_BIT, 0, - "integer constant", - (struct objfile *)NULL); - SYMBOL_TYPE (sym) = int_const_type; - SYMBOL_VALUE (sym) = atoi (p); - SYMBOL_CLASS (sym) = LOC_CONST; - } - break; - case 'e': - /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value - can be represented as integral. - e.g. "b:c=e6,0" for "const b = blob1" - (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ - { - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_TYPE (sym) = read_type (&p, objfile); - - if (*p != ',') - { - SYMBOL_TYPE (sym) = error_type (&p); - break; - } - ++p; - - /* If the value is too big to fit in an int (perhaps because - it is unsigned), or something like that, we silently get - a bogus value. The type and everything else about it is - correct. Ideally, we should be using whatever we have - available for parsing unsigned and long long values, - however. */ - SYMBOL_VALUE (sym) = atoi (p); - } - break; - default: - { - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_TYPE (sym) = error_type (&p); - } - } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &file_symbols); - return sym; - - case 'C': - /* The name of a caught exception. */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_LABEL; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_VALUE_ADDRESS (sym) = valu; - add_symbol_to_list (sym, &local_symbols); - break; - - case 'f': - /* A static function definition. */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &file_symbols); - /* fall into process_function_types. */ - - process_function_types: - /* Function result types are described as the result type in stabs. - We need to convert this to the function-returning-type-X type - in GDB. E.g. "int" is converted to "function returning int". */ - if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC) - { -#if 0 - /* This code doesn't work -- it needs to realloc and can't. */ - /* Attempt to set up to record a function prototype... */ - struct type *new = alloc_type (objfile); - - /* Generate a template for the type of this function. The - types of the arguments will be added as we read the symbol - table. */ - *new = *lookup_function_type (SYMBOL_TYPE(sym)); - SYMBOL_TYPE(sym) = new; - TYPE_OBJFILE (new) = objfile; - in_function_type = new; -#else - SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym)); -#endif - } - /* 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); - } - break; - - case 'F': - /* A global function definition. */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &global_symbols); - goto process_function_types; - - case 'G': - /* For a class G (global) symbol, it appears that the - value is not correct. It is necessary to search for the - 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; - add_symbol_to_list (sym, &global_symbols); - break; - - /* This case is faked by a conditional above, - when there is no code letter in the dbx data. - Dbx data never actually contains 'l'. */ - case 's': - case 'l': - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_LOCAL; - SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &local_symbols); - break; - - case 'p': - if (*p == 'F') - /* pF is a two-letter code that means a function parameter in Fortran. - The type-number specifies the type of the return value. - Translate it into a pointer-to-function type. */ - { - p++; - SYMBOL_TYPE (sym) - = lookup_pointer_type - (lookup_function_type (read_type (&p, objfile))); - } - else - SYMBOL_TYPE (sym) = read_type (&p, objfile); - - /* Normally this is a parameter, a LOC_ARG. On the i960, it - can also be a LOC_LOCAL_ARG depending on symbol type. */ -#ifndef DBX_PARM_SYMBOL_CLASS -#define DBX_PARM_SYMBOL_CLASS(type) LOC_ARG -#endif - - SYMBOL_CLASS (sym) = DBX_PARM_SYMBOL_CLASS (type); - SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; -#if 0 - /* This doesn't work yet. */ - add_param_to_type (&in_function_type, sym); -#endif - add_symbol_to_list (sym, &local_symbols); - -#if TARGET_BYTE_ORDER == LITTLE_ENDIAN - /* On little-endian machines, this crud is never necessary, and, - if the extra bytes contain garbage, is harmful. */ - break; -#else /* Big endian. */ - /* If it's gcc-compiled, if it says `short', believe it. */ - if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION) - break; - -#if !BELIEVE_PCC_PROMOTION - { - /* This is the signed type which arguments get promoted to. */ - static struct type *pcc_promotion_type; - /* This is the unsigned type which arguments get promoted to. */ - static struct type *pcc_unsigned_promotion_type; - - /* Call it "int" because this is mainly C lossage. */ - if (pcc_promotion_type == NULL) - pcc_promotion_type = - init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "int", NULL); - - if (pcc_unsigned_promotion_type == NULL) - pcc_unsigned_promotion_type = - init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, "unsigned int", NULL); - -#if defined(BELIEVE_PCC_PROMOTION_TYPE) - /* This macro is defined on machines (e.g. sparc) where - we should believe the type of a PCC 'short' argument, - but shouldn't believe the address (the address is - the address of the corresponding int). - - My guess is that this correction, as opposed to changing - the parameter to an 'int' (as done below, for PCC - on most machines), is the right thing to do - on all machines, but I don't want to risk breaking - something that already works. On most PCC machines, - the sparc problem doesn't come up because the calling - function has to zero the top bytes (not knowing whether - the called function wants an int or a short), so there - is little practical difference between an int and a short - (except perhaps what happens when the GDB user types - "print short_arg = 0x10000;"). - - Hacked for SunOS 4.1 by gnu@cygnus.com. In 4.1, the compiler - actually produces the correct address (we don't need to fix it - up). I made this code adapt so that it will offset the symbol - if it was pointing at an int-aligned location and not - otherwise. This way you can use the same gdb for 4.0.x and - 4.1 systems. - - If the parameter is shorter than an int, and is integral - (e.g. char, short, or unsigned equivalent), and is claimed to - be passed on an integer boundary, don't believe it! Offset the - parameter's address to the tail-end of that integer. */ - - if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type) - && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT - && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (pcc_promotion_type)) - { - SYMBOL_VALUE (sym) += TYPE_LENGTH (pcc_promotion_type) - - TYPE_LENGTH (SYMBOL_TYPE (sym)); - } - break; - -#else /* no BELIEVE_PCC_PROMOTION_TYPE. */ - - /* If PCC says a parameter is a short or a char, - it is really an int. */ - if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type) - && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT) - { - SYMBOL_TYPE (sym) = - TYPE_UNSIGNED (SYMBOL_TYPE (sym)) - ? pcc_unsigned_promotion_type - : pcc_promotion_type; - } - break; - -#endif /* no BELIEVE_PCC_PROMOTION_TYPE. */ - } -#endif /* !BELIEVE_PCC_PROMOTION. */ -#endif /* Big endian. */ - - case 'P': - /* acc seems to use P to delare the prototypes of functions that - are referenced by this file. gdb is not prepared to deal - with this extra information. FIXME, it ought to. */ - if (type == N_FUN) - { - read_type (&p, objfile); - goto process_prototype_types; - } - /*FALLTHROUGH*/ - - case 'R': - /* Parameter which is in a register. */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_REGPARM; - SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); - if (SYMBOL_VALUE (sym) >= NUM_REGS) - { - complain (®_value_complaint, SYMBOL_SOURCE_NAME (sym)); - SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ - } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &local_symbols); - break; - - case 'r': - /* Register variable (either global or local). */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_REGISTER; - SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); - if (SYMBOL_VALUE (sym) >= NUM_REGS) - { - complain (®_value_complaint, SYMBOL_SOURCE_NAME (sym)); - SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ - } - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - if (within_function) - { - /* Sun cc uses a pair of symbols, one 'p' and one 'r' with the same - name to represent an argument passed in a register. - GCC uses 'P' for the same case. So if we find such a symbol pair - we combine it into one 'P' symbol. For Sun cc we need to do this - regardless of REG_STRUCT_HAS_ADDR, because the compiler puts out - the 'p' symbol even if it never saves the argument onto the stack. - - On most machines, we want to preserve both symbols, so that - we can still get information about what is going on with the - stack (VAX for computing args_printed, using stack slots instead - of saved registers in backtraces, etc.). - - Note that this code illegally combines - main(argc) struct foo argc; { register struct foo argc; } - but this case is considered pathological and causes a warning - from a decent compiler. */ - - if (local_symbols - && local_symbols->nsyms > 0 -#ifndef USE_REGISTER_NOT_ARG - && 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) -#endif - ) - { - struct symbol *prev_sym; - prev_sym = local_symbols->symbol[local_symbols->nsyms - 1]; - if ((SYMBOL_CLASS (prev_sym) == LOC_REF_ARG - || SYMBOL_CLASS (prev_sym) == LOC_ARG) - && STREQ (SYMBOL_NAME (prev_sym), SYMBOL_NAME(sym))) - { - SYMBOL_CLASS (prev_sym) = LOC_REGPARM; - /* Use the type from the LOC_REGISTER; that is the type - that is actually in that register. */ - SYMBOL_TYPE (prev_sym) = SYMBOL_TYPE (sym); - SYMBOL_VALUE (prev_sym) = SYMBOL_VALUE (sym); - sym = prev_sym; - break; - } - } - add_symbol_to_list (sym, &local_symbols); - } - else - add_symbol_to_list (sym, &file_symbols); - break; - - case 'S': - /* Static symbol at top level of file */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_VALUE_ADDRESS (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &file_symbols); - break; - - case 't': - SYMBOL_TYPE (sym) = read_type (&p, objfile); - - /* For a nameless type, we don't want a create a symbol, thus we - did not use `sym'. Return without further processing. */ - if (nameless) return NULL; - - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - /* C++ vagaries: we may have a type which is derived from - a base type which did not have its name defined when the - derived class was output. We fill in the derived class's - base part member's name here in that case. */ - if (TYPE_NAME (SYMBOL_TYPE (sym)) != NULL) - if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION) - && TYPE_N_BASECLASSES (SYMBOL_TYPE (sym))) - { - int j; - for (j = TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)) - 1; j >= 0; j--) - if (TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) == 0) - TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) = - type_name_no_tag (TYPE_BASECLASS (SYMBOL_TYPE (sym), j)); - } - - if (TYPE_NAME (SYMBOL_TYPE (sym)) == NULL) - { - /* gcc-2.6 or later (when using -fvtable-thunks) - emits a unique named type for a vtable entry. - Some gdb code depends on that specific name. */ - extern const char vtbl_ptr_name[]; - - if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR - && strcmp (SYMBOL_NAME (sym), vtbl_ptr_name)) - || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC) - { - /* If we are giving a name to a type such as "pointer to - foo" or "function returning foo", we better not set - the TYPE_NAME. If the program contains "typedef char - *caddr_t;", we don't want all variables of type char - * to print as caddr_t. This is not just a - consequence of GDB's type management; PCC and GCC (at - least through version 2.4) both output variables of - either type char * or caddr_t with the type number - defined in the 't' symbol for caddr_t. If a future - compiler cleans this up it GDB is not ready for it - yet, but if it becomes ready we somehow need to - disable this check (without breaking the PCC/GCC2.4 - case). - - Sigh. - - Fortunately, this check seems not to be necessary - for anything except pointers or functions. */ - } - else - TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NAME (sym); - } - - add_symbol_to_list (sym, &file_symbols); - break; - - case 'T': - /* Struct, union, or enum tag. For GNU C++, this can be be followed - by 't' which means we are typedef'ing it as well. */ - synonym = *p == 't'; - - if (synonym) - { - p++; - type_synonym_name = obsavestring (SYMBOL_NAME (sym), - strlen (SYMBOL_NAME (sym)), - &objfile -> symbol_obstack); - } - /* The semantics of C++ state that "struct foo { ... }" also defines - a typedef for "foo". Unfortunately, cfront never makes the typedef - when translating C++ into C. We make the typedef here so that - "ptype foo" works as expected for cfront translated code. */ - else if (current_subfile->language == language_cplus) - { - synonym = 1; - type_synonym_name = obsavestring (SYMBOL_NAME (sym), - strlen (SYMBOL_NAME (sym)), - &objfile -> symbol_obstack); - } - - SYMBOL_TYPE (sym) = read_type (&p, objfile); - - /* For a nameless type, we don't want a create a symbol, thus we - did not use `sym'. Return without further processing. */ - if (nameless) return NULL; - - SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; - if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0) - TYPE_TAG_NAME (SYMBOL_TYPE (sym)) - = obconcat (&objfile -> type_obstack, "", "", SYMBOL_NAME (sym)); - add_symbol_to_list (sym, &file_symbols); - - if (synonym) - { - /* Clone the sym and then modify it. */ - register struct symbol *typedef_sym = (struct symbol *) - obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); - *typedef_sym = *sym; - SYMBOL_CLASS (typedef_sym) = LOC_TYPEDEF; - SYMBOL_VALUE (typedef_sym) = valu; - SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE; - if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) - TYPE_NAME (SYMBOL_TYPE (sym)) - = obconcat (&objfile -> type_obstack, "", "", SYMBOL_NAME (sym)); - add_symbol_to_list (typedef_sym, &file_symbols); - } - break; - - case 'V': - /* Static symbol of local scope */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_VALUE_ADDRESS (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - if (os9k_stabs) - add_symbol_to_list (sym, &global_symbols); - else - add_symbol_to_list (sym, &local_symbols); - break; - - case 'v': - /* Reference parameter */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_REF_ARG; - SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &local_symbols); - break; - - case 'X': - /* This is used by Sun FORTRAN for "function result value". - Sun claims ("dbx and dbxtool interfaces", 2nd ed) - that Pascal uses it too, but when I tried it Pascal used - "x:3" (local symbol) instead. */ - SYMBOL_TYPE (sym) = read_type (&p, objfile); - SYMBOL_CLASS (sym) = LOC_LOCAL; - SYMBOL_VALUE (sym) = valu; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &local_symbols); - break; - - default: - SYMBOL_TYPE (sym) = error_type (&p); - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_VALUE (sym) = 0; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &file_symbols); - break; - } - - /* When passing structures to a function, some systems sometimes pass - the address in a register, not the structure itself. - - 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 - && 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))) - 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). */ - if (SYMBOL_CLASS (sym) == LOC_ARG - && 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))) - SYMBOL_CLASS (sym) = LOC_REF_ARG; - - return sym; -} - - -/* Skip rest of this symbol and return an error type. - - General notes on error recovery: error_type always skips to the - end of the symbol (modulo cretinous dbx symbol name continuation). - Thus code like this: - - if (*(*pp)++ != ';') - return error_type (pp); - - is wrong because if *pp starts out pointing at '\0' (typically as the - result of an earlier error), it will be incremented to point to the - start of the next symbol, which might produce strange results, at least - if you run off the end of the string table. Instead use - - if (**pp != ';') - return error_type (pp); - ++*pp; - - or - - if (**pp != ';') - foo = error_type (pp); - else - ++*pp; - - And in case it isn't obvious, the point of all this hair is so the compiler - can define new types and new syntaxes, and old versions of the - debugger will be able to read the new symbol tables. */ - -static struct type * -error_type (pp) - char **pp; -{ - complain (&error_type_complaint); - while (1) - { - /* Skip to end of symbol. */ - while (**pp != '\0') - { - (*pp)++; - } - - /* Check for and handle cretinous dbx symbol name continuation! */ - if ((*pp)[-1] == '\\' || (*pp)[-1] == '?') - { - *pp = next_symbol_text (); - } - else - { - break; - } - } - return (builtin_type_error); -} - - -/* Read type information or a type definition; return the type. Even - though this routine accepts either type information or a type - definition, the distinction is relevant--some parts of stabsread.c - assume that type information starts with a digit, '-', or '(' in - deciding whether to call read_type. */ - -struct type * -read_type (pp, objfile) - register char **pp; - struct objfile *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 - there is no size attribute. */ - int type_size = -1; - - /* Used to distinguish string and bitstring from char-array and set. */ - int is_string = 0; - - /* Read type number if present. The type number may be omitted. - for instance in a two-dimensional array declared with type - "ar1;1;10;ar1;1;10;4". */ - if ((**pp >= '0' && **pp <= '9') - || **pp == '(' - || **pp == '-') - { - if (read_type_number (pp, typenums) != 0) - return error_type (pp); - - /* Type is not being defined here. Either it already exists, - or this is a forward reference to it. dbx_alloc_type handles - both cases. */ - if (**pp != '=') - 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); - 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); - } - else - { - /* 'typenums=' not present, type is anonymous. Read and return - the definition, but don't put it in the type vector. */ - typenums[0] = typenums[1] = -1; - (*pp)++; - } - - type_descriptor = (*pp)[-1]; - switch (type_descriptor) - { - case 'x': - { - enum type_code code; - - /* Used to index through file_symbols. */ - struct pending *ppt; - int i; - - /* Name including "struct", etc. */ - char *type_name; - - { - char *from, *to, *p, *q1, *q2; - - /* Set the type code according to the following letter. */ - switch ((*pp)[0]) - { - case 's': - code = TYPE_CODE_STRUCT; - break; - case 'u': - code = TYPE_CODE_UNION; - break; - case 'e': - code = TYPE_CODE_ENUM; - break; - default: - { - /* Complain and keep going, so compilers can invent new - cross-reference types. */ - static struct complaint msg = - {"Unrecognized cross-reference type `%c'", 0, 0}; - complain (&msg, (*pp)[0]); - code = TYPE_CODE_STRUCT; - break; - } - } - - q1 = strchr(*pp, '<'); - p = strchr(*pp, ':'); - if (p == NULL) - return error_type (pp); - while (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); - } - to = type_name = - (char *)obstack_alloc (&objfile->type_obstack, p - *pp + 1); - - /* Copy the name. */ - from = *pp + 1; - while (from < p) - *to++ = *from++; - *to = '\0'; - - /* Set the pointer ahead of the name which we just read, and - the colon. */ - *pp = from + 1; - } - - /* Now check to see whether the type has already been - declared. This was written for arrays of cross-referenced - types before we had TYPE_CODE_TARGET_STUBBED, so I'm pretty - sure it is not necessary anymore. But it might be a good - idea, to save a little memory. */ - - for (ppt = file_symbols; ppt; ppt = ppt->next) - for (i = 0; i < ppt->nsyms; i++) - { - struct symbol *sym = ppt->symbol[i]; - - if (SYMBOL_CLASS (sym) == LOC_TYPEDEF - && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE - && (TYPE_CODE (SYMBOL_TYPE (sym)) == code) - && STREQ (SYMBOL_NAME (sym), type_name)) - { - obstack_free (&objfile -> type_obstack, type_name); - type = SYMBOL_TYPE (sym); - return type; - } - } - - /* Didn't find the type to which this refers, so we must - be dealing with a forward reference. Allocate a type - structure for it, and keep track of it so we can - fill in the rest of the fields when we get the full - type. */ - type = dbx_alloc_type (typenums, objfile); - TYPE_CODE (type) = code; - TYPE_TAG_NAME (type) = type_name; - INIT_CPLUS_SPECIFIC(type); - TYPE_FLAGS (type) |= TYPE_FLAG_STUB; - - add_undefined_type (type); - return type; - } - - case '-': /* RS/6000 built-in type */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '(': - - { - char *pp_saved; - - (*pp)--; - pp_saved = *pp; - - /* Peek ahead at the number to detect void. */ - if (read_type_number (pp, xtypenums) != 0) - return error_type (pp); - - 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); - 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); - memcpy (type, xtype, sizeof (struct type)); - - /* 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; - } - if (typenums[0] != -1) - *dbx_lookup_type (typenums) = type; - 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 - and making the typenums point to the new one. This is because there - may already be pointers to the existing type (if it had been - forward-referenced), and we must change it to a pointer, function, - reference, or whatever, *in-place*. */ - - case '*': - type1 = read_type (pp, objfile); - type = make_pointer_type (type1, dbx_lookup_type (typenums)); - break; - - case '&': /* Reference to another type */ - type1 = read_type (pp, objfile); - type = make_reference_type (type1, dbx_lookup_type (typenums)); - break; - - case 'f': /* Function returning another type */ - if (os9k_stabs && **pp == '(') - { - /* Function prototype; parse it. - We must conditionalize this on os9k_stabs because otherwise - it could be confused with a Sun-style (1,3) typenumber - (I think). */ - struct type *t; - ++*pp; - while (**pp != ')') - { - t = read_type(pp, objfile); - if (**pp == ',') ++*pp; - } - } - type1 = read_type (pp, objfile); - type = make_function_type (type1, dbx_lookup_type (typenums)); - break; - - case 'k': /* Const qualifier on some type (Sun) */ - case 'c': /* Const qualifier on some type (OS9000) */ - /* Because 'c' means other things to AIX and 'k' is perfectly good, - only accept 'c' in the os9k_stabs case. */ - if (type_descriptor == 'c' && !os9k_stabs) - return error_type (pp); - type = read_type (pp, objfile); - /* FIXME! For now, we ignore const and volatile qualifiers. */ - break; - - case 'B': /* Volatile qual on some type (Sun) */ - case 'i': /* Volatile qual on some type (OS9000) */ - /* Because 'i' means other things to AIX and 'B' is perfectly good, - only accept 'i' in the os9k_stabs case. */ - if (type_descriptor == 'i' && !os9k_stabs) - return error_type (pp); - type = 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; - - if (**pp != ',') - /* Invalid member type data format. */ - return error_type (pp); - ++*pp; - - memtype = read_type (pp, objfile); - type = dbx_alloc_type (typenums, objfile); - smash_to_member_type (type, domain, memtype); - } - break; - - case '#': /* Method (class & fn) type */ - if ((*pp)[0] == '#') - { - /* We'll get the parameter types from the name. */ - struct type *return_type; - - (*pp)++; - return_type = read_type (pp, objfile); - if (*(*pp)++ != ';') - complain (&invalid_member_complaint, symnum); - type = allocate_stub_method (return_type); - if (typenums[0] != -1) - *dbx_lookup_type (typenums) = type; - } - else - { - struct type *domain = read_type (pp, objfile); - struct type *return_type; - struct type **args; - - if (**pp != ',') - /* Invalid member type data format. */ - return error_type (pp); - else - ++(*pp); - - return_type = read_type (pp, objfile); - args = read_args (pp, ';', objfile); - type = dbx_alloc_type (typenums, objfile); - smash_to_method_type (type, domain, return_type, args); - } - break; - - case 'r': /* Range type */ - type = read_range_type (pp, typenums, objfile); - if (typenums[0] != -1) - *dbx_lookup_type (typenums) = type; - break; - - case 'b': - if (os9k_stabs) - /* Const and volatile qualified type. */ - type = read_type (pp, objfile); - else - { - /* Sun ACC builtin int type */ - type = read_sun_builtin_type (pp, typenums, objfile); - if (typenums[0] != -1) - *dbx_lookup_type (typenums) = type; - } - break; - - case 'R': /* Sun ACC builtin float type */ - type = read_sun_floating_type (pp, typenums, objfile); - if (typenums[0] != -1) - *dbx_lookup_type (typenums) = type; - break; - - case 'e': /* Enumeration type */ - type = dbx_alloc_type (typenums, objfile); - type = read_enum_type (pp, type, objfile); - if (typenums[0] != -1) - *dbx_lookup_type (typenums) = type; - break; - - case 's': /* Struct type */ - case 'u': /* Union type */ - type = dbx_alloc_type (typenums, objfile); - if (!TYPE_NAME (type)) - { - TYPE_NAME (type) = type_synonym_name; - } - type_synonym_name = NULL; - switch (type_descriptor) - { - case 's': - TYPE_CODE (type) = TYPE_CODE_STRUCT; - break; - case 'u': - TYPE_CODE (type) = TYPE_CODE_UNION; - break; - } - type = read_struct_type (pp, type, objfile); - break; - - case 'a': /* Array type */ - if (**pp != 'r') - return error_type (pp); - ++*pp; - - type = dbx_alloc_type (typenums, objfile); - type = read_array_type (pp, type, objfile); - if (is_string) - TYPE_CODE (type) = TYPE_CODE_STRING; - break; - - case 'S': - type1 = read_type (pp, objfile); - type = create_set_type ((struct type*) NULL, type1); - if (is_string) - TYPE_CODE (type) = TYPE_CODE_BITSTRING; - if (typenums[0] != -1) - *dbx_lookup_type (typenums) = type; - break; - - default: - --*pp; /* Go back to the symbol in error */ - /* Particularly important if it was \0! */ - return error_type (pp); - } - - if (type == 0) - { - warning ("GDB internal error, type is NULL in stabsread.c\n"); - return error_type (pp); - } - - /* Size specified in a type attribute overrides any other size. */ - if (type_size != -1) - TYPE_LENGTH (type) = type_size / TARGET_CHAR_BIT; - - return type; -} - -/* RS/6000 xlc/dbx combination uses a set of builtin types, starting from -1. - Return the proper type node for a given builtin type number. */ - -static struct type * -rs6000_builtin_type (typenum) - int typenum; -{ - /* We recognize types numbered from -NUMBER_RECOGNIZED to -1. */ -#define NUMBER_RECOGNIZED 30 - /* This includes an empty slot for type number -0. */ - static struct type *negative_types[NUMBER_RECOGNIZED + 1]; - struct type *rettype = NULL; - - if (typenum >= 0 || typenum < -NUMBER_RECOGNIZED) - { - complain (&rs6000_builtin_complaint, typenum); - return builtin_type_error; - } - if (negative_types[-typenum] != NULL) - return negative_types[-typenum]; - -#if TARGET_CHAR_BIT != 8 - #error This code wrong for TARGET_CHAR_BIT not 8 - /* These definitions all assume that TARGET_CHAR_BIT is 8. I think - that if that ever becomes not true, the correct fix will be to - make the size in the struct type to be in bits, not in units of - TARGET_CHAR_BIT. */ -#endif - - switch (-typenum) - { - case 1: - /* The size of this and all the other types are fixed, defined - by the debugging format. If there is a type called "int" which - is other than 32 bits, then it should use a new negative type - number (or avoid negative type numbers for that case). - See stabs.texinfo. */ - rettype = init_type (TYPE_CODE_INT, 4, 0, "int", NULL); - break; - case 2: - rettype = init_type (TYPE_CODE_INT, 1, 0, "char", NULL); - break; - case 3: - rettype = init_type (TYPE_CODE_INT, 2, 0, "short", NULL); - break; - case 4: - rettype = init_type (TYPE_CODE_INT, 4, 0, "long", NULL); - break; - case 5: - rettype = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, - "unsigned char", NULL); - break; - case 6: - rettype = init_type (TYPE_CODE_INT, 1, 0, "signed char", NULL); - break; - case 7: - rettype = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, - "unsigned short", NULL); - break; - case 8: - rettype = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED, - "unsigned int", NULL); - break; - case 9: - rettype = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED, - "unsigned", NULL); - case 10: - rettype = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED, - "unsigned long", NULL); - break; - case 11: - rettype = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL); - break; - case 12: - /* IEEE single precision (32 bit). */ - rettype = init_type (TYPE_CODE_FLT, 4, 0, "float", NULL); - break; - case 13: - /* IEEE double precision (64 bit). */ - rettype = init_type (TYPE_CODE_FLT, 8, 0, "double", NULL); - break; - case 14: - /* This is an IEEE double on the RS/6000, and different machines with - different sizes for "long double" should use different negative - type numbers. See stabs.texinfo. */ - rettype = init_type (TYPE_CODE_FLT, 8, 0, "long double", NULL); - break; - case 15: - rettype = init_type (TYPE_CODE_INT, 4, 0, "integer", NULL); - break; - case 16: - rettype = init_type (TYPE_CODE_BOOL, 4, 0, "boolean", NULL); - break; - case 17: - rettype = init_type (TYPE_CODE_FLT, 4, 0, "short real", NULL); - break; - case 18: - rettype = init_type (TYPE_CODE_FLT, 8, 0, "real", NULL); - break; - case 19: - rettype = init_type (TYPE_CODE_ERROR, 0, 0, "stringptr", NULL); - break; - case 20: - rettype = init_type (TYPE_CODE_CHAR, 1, TYPE_FLAG_UNSIGNED, - "character", NULL); - break; - case 21: - rettype = init_type (TYPE_CODE_BOOL, 1, TYPE_FLAG_UNSIGNED, - "logical*1", NULL); - break; - case 22: - rettype = init_type (TYPE_CODE_BOOL, 2, TYPE_FLAG_UNSIGNED, - "logical*2", NULL); - break; - case 23: - rettype = init_type (TYPE_CODE_BOOL, 4, TYPE_FLAG_UNSIGNED, - "logical*4", NULL); - break; - case 24: - rettype = init_type (TYPE_CODE_BOOL, 4, TYPE_FLAG_UNSIGNED, - "logical", NULL); - break; - case 25: - /* Complex type consisting of two IEEE single precision values. */ - rettype = init_type (TYPE_CODE_ERROR, 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); - break; - case 27: - rettype = init_type (TYPE_CODE_INT, 1, 0, "integer*1", NULL); - break; - case 28: - rettype = init_type (TYPE_CODE_INT, 2, 0, "integer*2", NULL); - break; - case 29: - rettype = init_type (TYPE_CODE_INT, 4, 0, "integer*4", NULL); - break; - case 30: - rettype = init_type (TYPE_CODE_CHAR, 2, 0, "wchar", NULL); - break; - } - negative_types[-typenum] = rettype; - return rettype; -} - -/* 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: - - NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ; - - An example with two member functions is: - - afunc1::20=##15;:i;2A.;afunc2::20:i;2A.; - - For the case of overloaded operators, the format is op$::*.funcs, where - $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator - name (such as `+=') and `.' marks the end of the operator name. - - Returns 1 for success, 0 for failure. */ - -static int -read_member_functions (fip, pp, type, objfile) - struct field_info *fip; - char **pp; - struct type *type; - struct objfile *objfile; -{ - 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; - register char *p; - - /* Process each list until we find something that is not a member function - or find the end of the functions. */ - - while (**pp != ';') - { - /* We should be positioned at the start of the function name. - Scan forward to find the first ':' and if it is not the - first of a "::" delimiter, then this is not a member function. */ - p = *pp; - while (*p != ':') - { - p++; - } - if (p[1] != ':') - { - break; - } - - 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)); - - if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == CPLUS_MARKER) - { - /* This is a completely wierd case. In order to stuff in the - names that might contain colons (the usual name delimiter), - Mike Tiemann defined a different name format which is - signalled if the identifier is "op$". In that case, the - format is "op$::XXXX." where XXXX is the name. This is - used for names like "+" or "=". YUUUUUUUK! FIXME! */ - /* This lets the user type "break operator+". - We could just put in "+" as the name, but that wouldn't - work for "*". */ - static char opname[32] = {'o', 'p', CPLUS_MARKER}; - char *o = opname + 3; - - /* Skip past '::'. */ - *pp = p + 2; - - STABS_CONTINUE (pp); - p = *pp; - while (*p != '.') - { - *o++ = *p++; - } - main_fn_name = savestring (opname, o - opname); - /* Skip past '.' */ - *pp = p + 1; - } - else - { - main_fn_name = savestring (*pp, p - *pp); - /* Skip past '::'. */ - *pp = p + 2; - } - new_fnlist -> fn_fieldlist.name = main_fn_name; - - do - { - new_sublist = - (struct next_fnfield *) xmalloc (sizeof (struct next_fnfield)); - make_cleanup (free, new_sublist); - memset (new_sublist, 0, sizeof (struct next_fnfield)); - - /* Check for and handle cretinous dbx symbol name continuation! */ - if (look_ahead_type == NULL) - { - /* Normal case. */ - STABS_CONTINUE (pp); - - new_sublist -> fn_field.type = read_type (pp, objfile); - if (**pp != ':') - { - /* Invalid symtab info for member function. */ - return 0; - } - } - else - { - /* g++ version 1 kludge */ - new_sublist -> fn_field.type = look_ahead_type; - look_ahead_type = NULL; - } - - (*pp)++; - p = *pp; - while (*p != ';') - { - p++; - } - - /* 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; - } - new_sublist -> fn_field.physname = savestring (*pp, p - *pp); - *pp = p + 1; - - /* Set this member function's visibility fields. */ - switch (*(*pp)++) - { - case VISIBILITY_PRIVATE: - new_sublist -> fn_field.is_private = 1; - break; - case VISIBILITY_PROTECTED: - new_sublist -> fn_field.is_protected = 1; - break; - } - - STABS_CONTINUE (pp); - switch (**pp) - { - case 'A': /* Normal functions. */ - new_sublist -> fn_field.is_const = 0; - new_sublist -> fn_field.is_volatile = 0; - (*pp)++; - break; - case 'B': /* `const' member functions. */ - new_sublist -> fn_field.is_const = 1; - new_sublist -> fn_field.is_volatile = 0; - (*pp)++; - break; - case 'C': /* `volatile' member function. */ - new_sublist -> fn_field.is_const = 0; - new_sublist -> fn_field.is_volatile = 1; - (*pp)++; - break; - case 'D': /* `const volatile' member function. */ - new_sublist -> fn_field.is_const = 1; - new_sublist -> fn_field.is_volatile = 1; - (*pp)++; - break; - case '*': /* File compiled with g++ version 1 -- no info */ - case '?': - case '.': - break; - default: - complain (&const_vol_complaint, **pp); - break; - } - - switch (*(*pp)++) - { - case '*': - { - int nbits; - /* virtual member function, followed by index. - The sign bit is set to distinguish pointers-to-methods - from virtual function indicies. Since the array is - in words, the quantity must be shifted left by 1 - on 16 bit machine, and by 2 on 32 bit machine, forcing - the sign bit out, and usable as a valid index into - the array. Remove the sign bit here. */ - new_sublist -> fn_field.voffset = - (0x7fffffff & read_huge_number (pp, ';', &nbits)) + 2; - if (nbits != 0) - return 0; - - STABS_CONTINUE (pp); - if (**pp == ';' || **pp == '\0') - { - /* Must be g++ version 1. */ - new_sublist -> fn_field.fcontext = 0; - } - else - { - /* Figure out from whence this virtual function came. - It may belong to virtual function table of - one of its baseclasses. */ - look_ahead_type = read_type (pp, objfile); - if (**pp == ':') - { - /* g++ version 1 overloaded methods. */ - } - else - { - new_sublist -> fn_field.fcontext = look_ahead_type; - if (**pp != ';') - { - return 0; - } - else - { - ++*pp; - } - look_ahead_type = NULL; - } - } - break; - } - case '?': - /* static member function. */ - new_sublist -> fn_field.voffset = VOFFSET_STATIC; - if (strncmp (new_sublist -> fn_field.physname, - main_fn_name, strlen (main_fn_name))) - { - new_sublist -> fn_field.is_stub = 1; - } - break; - - default: - /* error */ - complain (&member_fn_complaint, (*pp)[-1]); - /* Fall through into normal member function. */ - - case '.': - /* normal member function. */ - new_sublist -> fn_field.voffset = 0; - new_sublist -> fn_field.fcontext = 0; - break; - } - - new_sublist -> next = sublist; - sublist = new_sublist; - length++; - STABS_CONTINUE (pp); - } - while (**pp != ';' && **pp != '\0'); - - (*pp)++; - - 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); - } - - if (nfn_fields) - { - ALLOCATE_CPLUS_STRUCT_TYPE (type); - 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; - } - - return 1; -} - -/* Special GNU C++ name. - - Returns 1 for success, 0 for failure. "failure" means that we can't - keep parsing and it's time for error_type(). */ - -static int -read_cpp_abbrev (fip, pp, type, objfile) - struct field_info *fip; - char **pp; - struct type *type; - struct objfile *objfile; -{ - register char *p; - char *name; - char cpp_abbrev; - struct type *context; - - p = *pp; - if (*++p == 'v') - { - name = NULL; - cpp_abbrev = *++p; - - *pp = p + 1; - - /* At this point, *pp points to something like "22:23=*22...", - where the type number before the ':' is the "context" and - everything after is a regular type definition. Lookup the - type, find it's name, and construct the field name. */ - - context = read_type (pp, objfile); - - switch (cpp_abbrev) - { - case 'f': /* $vf -- a virtual function table pointer */ - fip->list->field.name = - obconcat (&objfile->type_obstack, vptr_name, "", ""); - break; - - case 'b': /* $vb -- a virtual bsomethingorother */ - name = type_name_no_tag (context); - if (name == NULL) - { - complain (&invalid_cpp_type_complaint, symnum); - name = "FOO"; - } - fip->list->field.name = - obconcat (&objfile->type_obstack, vb_name, name, ""); - break; - - default: - complain (&invalid_cpp_abbrev_complaint, *pp); - fip->list->field.name = - obconcat (&objfile->type_obstack, - "INVALID_CPLUSPLUS_ABBREV", "", ""); - break; - } - - /* At this point, *pp points to the ':'. Skip it and read the - field type. */ - - p = ++(*pp); - if (p[-1] != ':') - { - complain (&invalid_cpp_abbrev_complaint, *pp); - return 0; - } - fip->list->field.type = read_type (pp, objfile); - if (**pp == ',') - (*pp)++; /* Skip the comma. */ - else - return 0; - - { - int nbits; - fip->list->field.bitpos = read_huge_number (pp, ';', &nbits); - if (nbits != 0) - return 0; - } - /* This field is unpacked. */ - fip->list->field.bitsize = 0; - fip->list->visibility = VISIBILITY_PRIVATE; - } - else - { - complain (&invalid_cpp_abbrev_complaint, *pp); - /* We have no idea what syntax an unrecognized abbrev would have, so - better return 0. If we returned 1, we would need to at least advance - *pp to avoid an infinite loop. */ - return 0; - } - return 1; -} - -static void -read_one_struct_field (fip, pp, p, type, objfile) - struct field_info *fip; - char **pp; - char *p; - struct type *type; - struct objfile *objfile; -{ - fip -> list -> field.name = - obsavestring (*pp, p - *pp, &objfile -> type_obstack); - *pp = p + 1; - - /* This means we have a visibility for a field coming. */ - if (**pp == '/') - { - (*pp)++; - fip -> list -> visibility = *(*pp)++; - } - else - { - /* normal dbx-style format, no explicit visibility */ - fip -> list -> visibility = VISIBILITY_PUBLIC; - } - - fip -> list -> field.type = read_type (pp, objfile); - if (**pp == ':') - { - p = ++(*pp); -#if 0 - /* Possible future hook for nested types. */ - if (**pp == '!') - { - fip -> list -> field.bitpos = (long)-2; /* nested type */ - p = ++(*pp); - } - else -#endif - { - /* Static class member. */ - fip -> list -> field.bitpos = (long) -1; - } - while (*p != ';') - { - p++; - } - fip -> list -> field.bitsize = (long) savestring (*pp, p - *pp); - *pp = p + 1; - return; - } - else if (**pp != ',') - { - /* Bad structure-type format. */ - complain (&stabs_general_complaint, "bad structure-type format"); - return; - } - - (*pp)++; /* Skip the comma. */ - - { - int nbits; - fip -> list -> field.bitpos = 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); - if (nbits != 0) - { - complain (&stabs_general_complaint, "bad structure-type format"); - return; - } - } - - if (fip -> list -> field.bitpos == 0 && fip -> list -> field.bitsize == 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 - this case is to use VISIBILITY_IGNORE, but that is a recent - invention. (2) It is a 0-size array. For example - union { int num; char str[0]; } foo. Printing "" for - str in "p foo" is OK, since foo.str (and thus foo.str[3]) - will continue to work, and a 0-size array as a whole doesn't - have any contents to print. - - I suspect this probably could also happen with gcc -gstabs (not - -gstabs+) for static fields, and perhaps other C++ extensions. - Hopefully few people use -gstabs with gdb, since it is intended - for dbx compatibility. */ - - /* Ignore this field. */ - fip -> list-> visibility = VISIBILITY_IGNORE; - } - else - { - /* Detect an unpacked field and mark it as such. - dbx gives a bit size for all fields. - 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_ENUM) - { - fip -> list -> field.bitsize = 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) - ) - ) - && - fip -> list -> field.bitpos % 8 == 0) - { - fip -> list -> field.bitsize = 0; - } - } -} - - -/* Read struct or class data fields. They have the form: - - NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ; - - At the end, we see a semicolon instead of a field. - - In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for - a static field. - - The optional VISIBILITY is one of: - - '/0' (VISIBILITY_PRIVATE) - '/1' (VISIBILITY_PROTECTED) - '/2' (VISIBILITY_PUBLIC) - '/9' (VISIBILITY_IGNORE) - - or nothing, for C style fields with public visibility. - - Returns 1 for success, 0 for failure. */ - -static int -read_struct_fields (fip, pp, type, objfile) - struct field_info *fip; - char **pp; - struct type *type; - struct objfile *objfile; -{ - register char *p; - struct nextfield *new; - - /* We better set p right now, in case there are no fields at all... */ - - p = *pp; - - /* Read each data member type until we find the terminating ';' at the end of - the data member list, or break for some other reason such as finding the - start of the member function list. */ - - while (**pp != ';') - { - if (os9k_stabs && **pp == ',') break; - STABS_CONTINUE (pp); - /* Get space to record the next field's data. */ - new = (struct nextfield *) xmalloc (sizeof (struct nextfield)); - make_cleanup (free, new); - memset (new, 0, sizeof (struct nextfield)); - new -> next = fip -> list; - fip -> list = new; - - /* Get the field name. */ - p = *pp; - - /* If is starts with CPLUS_MARKER it is a special abbreviation, - unless the CPLUS_MARKER is followed by an underscore, in - which case it is just the name of an anonymous type, which we - should handle like any other type name. We accept either '$' - or '.', because a field name can never contain one of these - characters except as a CPLUS_MARKER (we probably should be - doing that in most parts of GDB). */ - - if ((*p == '$' || *p == '.') && p[1] != '_') - { - if (!read_cpp_abbrev (fip, pp, type, objfile)) - return 0; - continue; - } - - /* Look for the ':' that separates the field name from the field - values. Data members are delimited by a single ':', while member - functions are delimited by a pair of ':'s. When we hit the member - functions (if any), terminate scan loop and return. */ - - while (*p != ':' && *p != '\0') - { - p++; - } - if (*p == '\0') - return 0; - - /* Check to see if we have hit the member functions yet. */ - if (p[1] == ':') - { - break; - } - read_one_struct_field (fip, pp, p, type, objfile); - } - if (p[0] == ':' && p[1] == ':') - { - /* chill the list of fields: the last entry (at the head) is a - partially constructed entry which we now scrub. */ - fip -> list = fip -> list -> next; - } - return 1; -} - -/* The stabs for C++ derived classes contain baseclass information which - is marked by a '!' character after the total size. This function is - called when we encounter the baseclass marker, and slurps up all the - baseclass information. - - Immediately following the '!' marker is the number of base classes that - the class is derived from, followed by information for each base class. - For each base class, there are two visibility specifiers, a bit offset - to the base class information within the derived class, a reference to - the type for the base class, and a terminating semicolon. - - A typical example, with two base classes, would be "!2,020,19;0264,21;". - ^^ ^ ^ ^ ^ ^ ^ - Baseclass information marker __________________|| | | | | | | - Number of baseclasses __________________________| | | | | | | - Visibility specifiers (2) ________________________| | | | | | - Offset in bits from start of class _________________| | | | | - Type number for base class ___________________________| | | | - Visibility specifiers (2) _______________________________| | | - Offset in bits from start of class ________________________| | - Type number of base class ____________________________________| - - Return 1 for success, 0 for (error-type-inducing) failure. */ - -static int -read_baseclasses (fip, pp, type, objfile) - struct field_info *fip; - char **pp; - struct type *type; - struct objfile *objfile; -{ - int i; - struct nextfield *new; - - if (**pp != '!') - { - return 1; - } - else - { - /* Skip the '!' baseclass information marker. */ - (*pp)++; - } - - ALLOCATE_CPLUS_STRUCT_TYPE (type); - { - int nbits; - TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits); - if (nbits != 0) - return 0; - } - -#if 0 - /* Some stupid compilers have trouble with the following, so break - it up into simpler expressions. */ - TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) - TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type))); -#else - { - 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; - } -#endif /* 0 */ - - 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; - new -> field.bitsize = 0; /* this should be an unpacked field! */ - - STABS_CONTINUE (pp); - switch (**pp) - { - case '0': - /* Nothing to do. */ - break; - case '1': - SET_TYPE_FIELD_VIRTUAL (type, i); - break; - default: - /* Unknown character. Complain and treat it as non-virtual. */ - { - static struct complaint msg = { - "Unknown virtual character `%c' for baseclass", 0, 0}; - complain (&msg, **pp); - } - } - ++(*pp); - - new -> visibility = *(*pp)++; - switch (new -> visibility) - { - case VISIBILITY_PRIVATE: - case VISIBILITY_PROTECTED: - case 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; - } - } - - { - int nbits; - - /* The remaining value is the bit offset of the portion of the object - corresponding to this baseclass. Always zero in the absence of - multiple inheritance. */ - - new -> field.bitpos = read_huge_number (pp, ',', &nbits); - if (nbits != 0) - return 0; - } - - /* The last piece of baseclass information is the type of the - base class. Read it, and remember it's type name as this - field's name. */ - - new -> field.type = read_type (pp, objfile); - new -> field.name = type_name_no_tag (new -> field.type); - - /* skip trailing ';' and bump count of number of fields seen */ - if (**pp == ';') - (*pp)++; - else - return 0; - } - return 1; -} - -/* The tail end of stabs for C++ classes that contain a virtual function - pointer contains a tilde, a %, and a type number. - The type number refers to the base class (possibly this class itself) which - contains the vtable pointer for the current class. - - This function is called when we have parsed all the method declarations, - so we can look for the vptr base class info. */ - -static int -read_tilde_fields (fip, pp, type, objfile) - struct field_info *fip; - char **pp; - struct type *type; - struct objfile *objfile; -{ - register char *p; - - STABS_CONTINUE (pp); - - /* If we are positioned at a ';', then skip it. */ - if (**pp == ';') - { - (*pp)++; - } - - if (**pp == '~') - { - (*pp)++; - - if (**pp == '=' || **pp == '+' || **pp == '-') - { - /* Obsolete flags that used to indicate the presence - of constructors and/or destructors. */ - (*pp)++; - } - - /* Read either a '%' or the final ';'. */ - if (*(*pp)++ == '%') - { - /* The next number is the type number of the base class - (possibly our own class) which supplies the vtable for - this class. Parse it out, and search that class to find - its vtable pointer, and install those into TYPE_VPTR_BASETYPE - and TYPE_VPTR_FIELDNO. */ - - struct type *t; - int i; - - t = read_type (pp, objfile); - p = (*pp)++; - while (*p != '\0' && *p != ';') - { - p++; - } - if (*p == '\0') - { - /* Premature end of symbol. */ - return 0; - } - - TYPE_VPTR_BASETYPE (type) = t; - if (type == t) /* Our own class provides vtbl ptr */ - { - for (i = TYPE_NFIELDS (t) - 1; - i >= TYPE_N_BASECLASSES (t); - --i) - { - if (! strncmp (TYPE_FIELD_NAME (t, i), vptr_name, - sizeof (vptr_name) - 1)) - { - TYPE_VPTR_FIELDNO (type) = i; - goto gotit; - } - } - /* Virtual function table field not found. */ - complain (&vtbl_notfound_complaint, TYPE_NAME (type)); - return 0; - } - else - { - TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t); - } - - gotit: - *pp = p + 1; - } - } - return 1; -} - -static int -attach_fn_fields_to_type (fip, type) - struct field_info *fip; - register struct type *type; -{ - register int n; - - for (n = 0; n < TYPE_N_BASECLASSES (type); n++) - { - if (TYPE_CODE (TYPE_BASECLASS (type, n)) == TYPE_CODE_UNDEF) - { - /* @@ Memory leak on objfile -> type_obstack? */ - return 0; - } - TYPE_NFN_FIELDS_TOTAL (type) += - TYPE_NFN_FIELDS_TOTAL (TYPE_BASECLASS (type, n)); - } - - for (n = TYPE_NFN_FIELDS (type); - fip -> fnlist != NULL; - fip -> fnlist = fip -> fnlist -> next) - { - --n; /* Circumvent Sun3 compiler bug */ - TYPE_FN_FIELDLISTS (type)[n] = fip -> fnlist -> fn_fieldlist; - } - 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. */ - -static int -attach_fields_to_type (fip, type, objfile) - struct field_info *fip; - register struct type *type; - struct objfile *objfile; -{ - register int nfields = 0; - register int non_public_fields = 0; - register struct nextfield *scan; - - /* Count up the number of fields that we have, as well as taking note of - whether or not there are any non-public fields, which requires us to - allocate and build the private_field_bits and protected_field_bits - bitfields. */ - - for (scan = fip -> list; scan != NULL; scan = scan -> next) - { - nfields++; - if (scan -> visibility != VISIBILITY_PUBLIC) - { - non_public_fields++; - } - } - - /* Now we know how many fields there are, and whether or not there are any - non-public fields. Record the field count, allocate space for the - array of fields, and create blank visibility 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 (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); - } - - /* 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 -> list -> field; - switch (fip -> list -> visibility) - { - case VISIBILITY_PRIVATE: - SET_TYPE_FIELD_PRIVATE (type, nfields); - break; - - case VISIBILITY_PROTECTED: - SET_TYPE_FIELD_PROTECTED (type, nfields); - break; - - case VISIBILITY_IGNORE: - SET_TYPE_FIELD_IGNORE (type, nfields); - break; - - case VISIBILITY_PUBLIC: - break; - - default: - /* Unknown visibility. Complain and treat it as public. */ - { - static struct complaint msg = { - "Unknown visibility `%c' for field", 0, 0}; - complain (&msg, fip -> list -> visibility); - } - break; - } - fip -> list = fip -> list -> next; - } - return 1; -} - -/* Read the description of a structure (or union type) and return an object - describing the type. - - PP points to a character pointer that points to the next unconsumed token - in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;", - *PP will point to "4a:1,0,32;;". - - TYPE points to an incomplete type that needs to be filled in. - - OBJFILE points to the current objfile from which the stabs information is - being read. (Note that it is redundant in that TYPE also contains a pointer - to this same objfile, so it might be a good idea to eliminate it. FIXME). - */ - -static struct type * -read_struct_type (pp, type, objfile) - char **pp; - struct type *type; - struct objfile *objfile; -{ - struct cleanup *back_to; - struct field_info fi; - - fi.list = NULL; - fi.fnlist = NULL; - - back_to = make_cleanup (null_cleanup, 0); - - INIT_CPLUS_SPECIFIC (type); - TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; - - /* First comes the total size in bytes. */ - - { - int nbits; - TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits); - if (nbits != 0) - return error_type (pp); - } - - /* 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_baseclasses (&fi, pp, type, objfile) - || !read_struct_fields (&fi, pp, type, objfile) - || !attach_fields_to_type (&fi, type, objfile) - || !read_member_functions (&fi, pp, type, objfile) - || !attach_fn_fields_to_type (&fi, type) - || !read_tilde_fields (&fi, pp, type, objfile)) - { - do_cleanups (back_to); - return (error_type (pp)); - } - - do_cleanups (back_to); - return (type); -} - -/* Read a definition of an array type, - and create and return a suitable type object. - Also creates a range type which represents the bounds of that - array. */ - -static struct type * -read_array_type (pp, type, objfile) - register char **pp; - register struct type *type; - struct objfile *objfile; -{ - struct type *index_type, *element_type, *range_type; - int lower, upper; - int adjustable = 0; - int nbits; - - /* Format of an array type: - "ar;lower;upper;". - OS9000: "arlower,upper;". - - Fortran adjustable arrays use Adigits or Tdigits for lower or upper; - for these, produce a type like float[][]. */ - - if (os9k_stabs) - index_type = builtin_type_int; - else - { - index_type = read_type (pp, objfile); - if (**pp != ';') - /* Improper format of array type decl. */ - return error_type (pp); - ++*pp; - } - - if (!(**pp >= '0' && **pp <= '9') && **pp != '-') - { - (*pp)++; - adjustable = 1; - } - lower = read_huge_number (pp, os9k_stabs ? ',' : ';', &nbits); - if (nbits != 0) - return error_type (pp); - - if (!(**pp >= '0' && **pp <= '9') && **pp != '-') - { - (*pp)++; - adjustable = 1; - } - upper = read_huge_number (pp, ';', &nbits); - if (nbits != 0) - return error_type (pp); - - element_type = read_type (pp, objfile); - - if (adjustable) - { - lower = 0; - upper = -1; - } - - range_type = - create_range_type ((struct type *) NULL, index_type, lower, upper); - type = create_array_type (type, element_type, range_type); - - /* If we have an array whose element type is not yet known, but whose - bounds *are* known, record it to be adjusted at the end of the file. */ - /* FIXME: Why check for zero length rather than TYPE_FLAG_STUB? I think - the two have the same effect except that the latter is cleaner and the - former would be wrong for types which really are zero-length (if we - have any). */ - - if (TYPE_LENGTH (element_type) == 0 && !adjustable) - { - TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB; - add_undefined_type (type); - } - - return type; -} - - -/* Read a definition of an enumeration type, - and create and return a suitable type object. - Also defines the symbols that represent the values of the type. */ - -static struct type * -read_enum_type (pp, type, objfile) - register char **pp; - register struct type *type; - struct objfile *objfile; -{ - register char *p; - char *name; - register long n; - register struct symbol *sym; - int nsyms = 0; - struct pending **symlist; - struct pending *osyms, *syms; - int o_nsyms; - int nbits; - -#if 0 - /* FIXME! The stabs produced by Sun CC merrily define things that ought - to be file-scope, between N_FN entries, using N_LSYM. What's a mother - to do? For now, force all enum values to file scope. */ - if (within_function) - symlist = &local_symbols; - else -#endif - symlist = &file_symbols; - osyms = *symlist; - o_nsyms = osyms ? osyms->nsyms : 0; - - if (os9k_stabs) - { - /* Size. Perhaps this does not have to be conditionalized on - os9k_stabs (assuming the name of an enum constant can't start - with a digit). */ - read_huge_number (pp, 0, &nbits); - if (nbits != 0) - return error_type (pp); - } - - /* Read the value-names and their values. - The input syntax is NAME:VALUE,NAME:VALUE, and so on. - A semicolon or comma instead of a NAME means the end. */ - while (**pp && **pp != ';' && **pp != ',') - { - STABS_CONTINUE (pp); - p = *pp; - while (*p != ':') p++; - name = obsavestring (*pp, p - *pp, &objfile -> symbol_obstack); - *pp = p + 1; - n = read_huge_number (pp, ',', &nbits); - if (nbits != 0) - return error_type (pp); - - sym = (struct symbol *) - obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = name; - SYMBOL_LANGUAGE (sym) = current_subfile -> language; - SYMBOL_CLASS (sym) = LOC_CONST; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - SYMBOL_VALUE (sym) = n; - add_symbol_to_list (sym, symlist); - nsyms++; - } - - if (**pp == ';') - (*pp)++; /* Skip the semicolon. */ - - /* Now fill in the fields of the type-structure. */ - - TYPE_LENGTH (type) = TARGET_INT_BIT / HOST_CHAR_BIT; - TYPE_CODE (type) = TYPE_CODE_ENUM; - TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; - TYPE_NFIELDS (type) = nsyms; - TYPE_FIELDS (type) = (struct field *) - TYPE_ALLOC (type, sizeof (struct field) * nsyms); - memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nsyms); - - /* Find the symbols for the values 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_VALUE (type, n) = 0; - TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym); - TYPE_FIELD_BITSIZE (type, n) = 0; - } - if (syms == osyms) - break; - } - - return type; -} - -/* Sun's ACC uses a somewhat saner method for specifying the builtin - typedefs in every file (for int, long, etc): - - type = b ; ; - signed = u or s. Possible c in addition to u or s (for char?). - offset = offset from high order bit to start bit of type. - width is # bytes in object of this type, nbits is # bits in type. - - The width/offset stuff appears to be for small objects stored in - larger ones (e.g. `shorts' in `int' registers). We ignore it for now, - FIXME. */ - -static struct type * -read_sun_builtin_type (pp, typenums, objfile) - char **pp; - int typenums[2]; - struct objfile *objfile; -{ - int type_bits; - int nbits; - int signed_type; - - switch (**pp) - { - case 's': - signed_type = 1; - break; - case 'u': - signed_type = 0; - break; - default: - return error_type (pp); - } - (*pp)++; - - /* 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. */ - - if (**pp == 'c') - (*pp)++; - - /* The first number appears to be the number of bytes occupied - by this type, except that unsigned short is 4 instead of 2. - Since this information is redundant with the third number, - we will ignore it. */ - read_huge_number (pp, ';', &nbits); - if (nbits != 0) - return error_type (pp); - - /* The second number is always 0, so ignore it too. */ - read_huge_number (pp, ';', &nbits); - if (nbits != 0) - return error_type (pp); - - /* The third number is the number of bits for this type. */ - type_bits = read_huge_number (pp, 0, &nbits); - if (nbits != 0) - return error_type (pp); - /* The type *should* end with a semicolon. If it are embedded - in a larger type the semicolon may be the only way to know where - the type ends. If this type is at the end of the stabstring we - can deal with the omitted semicolon (but we don't have to like - it). Don't bother to complain(), Sun's compiler omits the semicolon - for "void". */ - if (**pp == ';') - ++(*pp); - - if (type_bits == 0) - return init_type (TYPE_CODE_VOID, 1, - signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL, - objfile); - else - return init_type (TYPE_CODE_INT, - type_bits / TARGET_CHAR_BIT, - signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL, - objfile); -} - -static struct type * -read_sun_floating_type (pp, typenums, objfile) - char **pp; - int typenums[2]; - struct objfile *objfile; -{ - int nbits; - int details; - int nbytes; - - /* The first number has more details about the type, for example - FN_COMPLEX. */ - details = read_huge_number (pp, ';', &nbits); - if (nbits != 0) - return error_type (pp); - - /* The second number is the number of bytes occupied by this type */ - nbytes = read_huge_number (pp, ';', &nbits); - if (nbits != 0) - return error_type (pp); - - if (details == NF_COMPLEX || details == NF_COMPLEX16 - || 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_FLT, nbytes, 0, NULL, objfile); -} - -/* Read a number from the string pointed to by *PP. - The value of *PP is advanced over the number. - If END is nonzero, the character that ends the - number must match END, or an error happens; - and that character is skipped if it does match. - If END is zero, *PP is left pointing to that character. - - If the number fits in a long, set *BITS to 0 and return the value. - If not, set *BITS to be the number of bits in the number and return 0. - - If encounter garbage, set *BITS to -1 and return 0. */ - -static long -read_huge_number (pp, end, bits) - char **pp; - int end; - int *bits; -{ - char *p = *pp; - int sign = 1; - long n = 0; - int radix = 10; - char overflow = 0; - int nbits = 0; - int c; - long upper_limit; - - if (*p == '-') - { - sign = -1; - p++; - } - - /* Leading zero means octal. GCC uses this to output values larger - than an int (because that would be hard in decimal). */ - if (*p == '0') - { - radix = 8; - p++; - } - - if (os9k_stabs) - upper_limit = ULONG_MAX / radix; - else - upper_limit = LONG_MAX / radix; - - while ((c = *p++) >= '0' && c < ('0' + radix)) - { - if (n <= upper_limit) - { - n *= radix; - n += c - '0'; /* FIXME this overflows anyway */ - } - else - overflow = 1; - - /* This depends on large values being output in octal, which is - what GCC does. */ - if (radix == 8) - { - if (nbits == 0) - { - if (c == '0') - /* Ignore leading zeroes. */ - ; - else if (c == '1') - nbits = 1; - else if (c == '2' || c == '3') - nbits = 2; - else - nbits = 3; - } - else - nbits += 3; - } - } - if (end) - { - if (c && c != end) - { - if (bits != NULL) - *bits = -1; - return 0; - } - } - else - --p; - - *pp = p; - if (overflow) - { - if (nbits == 0) - { - /* Large decimal constants are an error (because it is hard to - count how many bits are in them). */ - if (bits != NULL) - *bits = -1; - return 0; - } - - /* -0x7f is the same as 0x80. So deal with it by adding one to - the number of bits. */ - if (sign == -1) - ++nbits; - if (bits) - *bits = nbits; - } - else - { - if (bits) - *bits = 0; - return n * sign; - } - /* It's *BITS which has the interesting information. */ - return 0; -} - -static struct type * -read_range_type (pp, typenums, objfile) - char **pp; - int typenums[2]; - struct objfile *objfile; -{ - int rangenums[2]; - long n2, n3; - int n2bits, n3bits; - int self_subrange; - struct type *result_type; - struct type *index_type; - - /* First comes a type we are a subrange of. - In C it is usually 0, 1 or the type being defined. */ - /* FIXME: according to stabs.texinfo and AIX doc, this can be a type-id - not just a type number. */ - if (read_type_number (pp, rangenums) != 0) - return error_type (pp); - self_subrange = (rangenums[0] == typenums[0] && - rangenums[1] == typenums[1]); - - /* A semicolon should now follow; skip it. */ - if (**pp == ';') - (*pp)++; - - /* The remaining two operands are usually lower and upper bounds - of the range. But in some special cases they mean something else. */ - n2 = read_huge_number (pp, ';', &n2bits); - n3 = read_huge_number (pp, ';', &n3bits); - - if (n2bits == -1 || n3bits == -1) - return error_type (pp); - - /* If limits are huge, must be large integral type. */ - if (n2bits != 0 || n3bits != 0) - { - char got_signed = 0; - char got_unsigned = 0; - /* Number of bits in the type. */ - int nbits = 0; - - /* Range from 0 to is an unsigned large integral type. */ - if ((n2bits == 0 && n2 == 0) && n3bits != 0) - { - got_unsigned = 1; - nbits = n3bits; - } - /* Range from to -1 is a large signed - integral type. Take care of the case where doesn't - fit in a long but -1 does. */ - else if ((n2bits != 0 && n3bits != 0 && n2bits == n3bits + 1) - || (n2bits != 0 && n3bits == 0 - && (n2bits == sizeof (long) * HOST_CHAR_BIT) - && n3 == LONG_MAX)) - { - got_signed = 1; - nbits = n2bits; - } - - if (got_signed || got_unsigned) - { - return init_type (TYPE_CODE_INT, nbits / TARGET_CHAR_BIT, - got_unsigned ? TYPE_FLAG_UNSIGNED : 0, NULL, - objfile); - } - else - return error_type (pp); - } - - /* A type defined as a subrange of itself, with bounds both 0, is void. */ - if (self_subrange && n2 == 0 && n3 == 0) - return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile); - - /* If n3 is zero and n2 is not, 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! - - GDB does not have complex types. - - 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. */ - - if (n3 == 0 && n2 > 0) - { - return init_type (TYPE_CODE_FLT, n2, 0, NULL, objfile); - } - - /* If the upper bound is -1, it must really be an unsigned int. */ - - else if (n2 == 0 && n3 == -1) - { - /* It is unsigned int or unsigned long. */ - /* GCC 2.3.3 uses this for long long too, but that is just a GDB 3.5 - compatibility hack. */ - return init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, - TYPE_FLAG_UNSIGNED, NULL, objfile); - } - - /* Special case: char is defined (Who knows why) as a subrange of - itself with range 0-127. */ - else if (self_subrange && n2 == 0 && n3 == 127) - return init_type (TYPE_CODE_INT, 1, 0, NULL, objfile); - - /* We used to do this only for subrange of self or subrange of int. */ - else if (n2 == 0) - { - if (n3 < 0) - /* n3 actually gives the size. */ - return init_type (TYPE_CODE_INT, - n3, TYPE_FLAG_UNSIGNED, - NULL, objfile); - if (n3 == 0xff) - return init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, NULL, objfile); - if (n3 == 0xffff) - return init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, NULL, objfile); - - /* -1 is used for the upper bound of (4 byte) "unsigned int" and - "unsigned long", and we already checked for that, - so don't need to test for it here. */ - } - /* I think this is for Convex "long long". Since I don't know whether - Convex sets self_subrange, I also accept that particular size regardless - of self_subrange. */ - else if (n3 == 0 && n2 < 0 - && (self_subrange - || n2 == - TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT)) - return init_type (TYPE_CODE_INT, - n2, 0, NULL, objfile); - else if (n2 == -n3 -1) - { - if (n3 == 0x7f) - return init_type (TYPE_CODE_INT, 1, 0, NULL, objfile); - if (n3 == 0x7fff) - return init_type (TYPE_CODE_INT, 2, 0, NULL, objfile); - if (n3 == 0x7fffffff) - return init_type (TYPE_CODE_INT, 4, 0, NULL, objfile); - } - - /* We have a real range type on our hands. Allocate space and - return a real pointer. */ - - /* At this point I don't have the faintest idea how to deal with - a self_subrange type; I'm going to assume that this is used - as an idiom, and that all of them are special cases. So . . . */ - if (self_subrange) - return error_type (pp); - - index_type = *dbx_lookup_type (rangenums); - if (index_type == NULL) - { - /* Does this actually ever happen? Is that why we are worrying - about dealing with it rather than just calling error_type? */ - - static struct type *range_type_index; - - complain (&range_type_base_complaint, rangenums[1]); - if (range_type_index == NULL) - range_type_index = - init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT, - 0, "range type index type", NULL); - index_type = range_type_index; - } - - result_type = create_range_type ((struct type *) NULL, index_type, n2, n3); - return (result_type); -} - -/* Read in an argument list. This is a list of types, separated by commas - and terminated with END. Return the list of types read in, or (struct type - **)-1 if there is an error. */ - -static struct type ** -read_args (pp, end, objfile) - char **pp; - int end; - struct objfile *objfile; -{ - /* FIXME! Remove this arbitrary limit! */ - struct type *types[1024], **rval; /* allow for fns of 1023 parameters */ - int n = 0; - - while (**pp != end) - { - if (**pp != ',') - /* Invalid argument list: no ','. */ - return (struct type **)-1; - (*pp)++; - STABS_CONTINUE (pp); - types[n++] = read_type (pp, objfile); - } - (*pp)++; /* get past `end' (the ':' character) */ - - if (n == 1) - { - rval = (struct type **) xmalloc (2 * sizeof (struct type *)); - } - else if (TYPE_CODE (types[n-1]) != TYPE_CODE_VOID) - { - rval = (struct type **) xmalloc ((n + 1) * sizeof (struct type *)); - memset (rval + n, 0, sizeof (struct type *)); - } - else - { - rval = (struct type **) xmalloc (n * sizeof (struct type *)); - } - memcpy (rval, types, n * sizeof (struct type *)); - return rval; -} - -/* Common block handling. */ - -/* List of symbols declared since the last BCOMM. This list is a tail - of local_symbols. When ECOMM is seen, the symbols on the list - are noted so their proper addresses can be filled in later, - using the common block base address gotten from the assembler - stabs. */ - -static struct pending *common_block; -static int common_block_i; - -/* Name of the current common block. We get it from the BCOMM instead of the - ECOMM to match IBM documentation (even though IBM puts the name both places - like everyone else). */ -static char *common_block_name; - -/* Process a N_BCOMM symbol. The storage for NAME is not guaranteed - to remain after this function returns. */ - -void -common_block_start (name, objfile) - char *name; - struct objfile *objfile; -{ - if (common_block_name != NULL) - { - static struct complaint msg = { - "Invalid symbol data: common block within common block", - 0, 0}; - complain (&msg); - } - common_block = local_symbols; - common_block_i = local_symbols ? local_symbols->nsyms : 0; - common_block_name = obsavestring (name, strlen (name), - &objfile -> symbol_obstack); -} - -/* Process a N_ECOMM symbol. */ - -void -common_block_end (objfile) - struct objfile *objfile; -{ - /* Symbols declared since the BCOMM are to have the common block - start address added in when we know it. common_block and - common_block_i point to the first symbol after the BCOMM in - the local_symbols list; copy the list and hang it off the - symbol for the common block name for later fixup. */ - int i; - struct symbol *sym; - struct pending *new = 0; - struct pending *next; - int j; - - if (common_block_name == NULL) - { - static struct complaint msg = {"ECOMM symbol unmatched by BCOMM", 0, 0}; - complain (&msg); - return; - } - - sym = (struct symbol *) - obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = common_block_name; - SYMBOL_CLASS (sym) = LOC_BLOCK; - - /* Now we copy all the symbols which have been defined since the BCOMM. */ - - /* Copy all the struct pendings before common_block. */ - for (next = local_symbols; - next != NULL && next != common_block; - next = next->next) - { - for (j = 0; j < next->nsyms; j++) - add_symbol_to_list (next->symbol[j], &new); - } - - /* Copy however much of COMMON_BLOCK we need. If COMMON_BLOCK is - NULL, it means copy all the local symbols (which we already did - above). */ - - if (common_block != NULL) - for (j = common_block_i; j < common_block->nsyms; j++) - add_symbol_to_list (common_block->symbol[j], &new); - - SYMBOL_TYPE (sym) = (struct type *) new; - - /* Should we be putting local_symbols back to what it was? - Does it matter? */ - - i = hashname (SYMBOL_NAME (sym)); - SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i]; - global_sym_chain[i] = sym; - common_block_name = NULL; -} - -/* Add a common block's start address to the offset of each symbol - declared to be in it (by being between a BCOMM/ECOMM pair that uses - the common block name). */ - -static void -fix_common_block (sym, valu) - struct symbol *sym; - int valu; -{ - struct pending *next = (struct pending *) SYMBOL_TYPE (sym); - for ( ; next; next = next->next) - { - register int j; - for (j = next->nsyms - 1; j >= 0; j--) - SYMBOL_VALUE_ADDRESS (next->symbol[j]) += valu; - } -} - - - -/* What about types defined as forward references inside of a small lexical - scope? */ -/* Add a type to the list of undefined types to be checked through - once this file has been read in. */ - -void -add_undefined_type (type) - struct type *type; -{ - if (undef_types_length == undef_types_allocated) - { - undef_types_allocated *= 2; - undef_types = (struct type **) - xrealloc ((char *) undef_types, - undef_types_allocated * sizeof (struct type *)); - } - undef_types[undef_types_length++] = type; -} - -/* Go through each undefined type, see if it's still undefined, and fix it - up if possible. We have two kinds of undefined types: - - TYPE_CODE_ARRAY: Array whose target type wasn't defined yet. - Fix: update array length using the element bounds - and the target type's length. - TYPE_CODE_STRUCT, TYPE_CODE_UNION: Structure whose fields were not - yet defined at the time a pointer to it was made. - Fix: Do a full lookup on the struct/union tag. */ -void -cleanup_undefined_types () -{ - struct type **type; - - for (type = undef_types; type < undef_types + undef_types_length; type++) - { - switch (TYPE_CODE (*type)) - { - - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - case TYPE_CODE_ENUM: - { - /* Check if it has been defined since. Need to do this here - as well as in check_stub_type to deal with the (legitimate in - C though not C++) case of several types with the same name - in different source files. */ - if (TYPE_FLAGS (*type) & TYPE_FLAG_STUB) - { - struct pending *ppt; - int i; - /* Name of the type, without "struct" or "union" */ - char *typename = TYPE_TAG_NAME (*type); - - if (typename == NULL) - { - static struct complaint msg = {"need a type name", 0, 0}; - complain (&msg); - break; - } - for (ppt = file_symbols; ppt; ppt = ppt->next) - { - for (i = 0; i < ppt->nsyms; i++) - { - struct symbol *sym = ppt->symbol[i]; - - if (SYMBOL_CLASS (sym) == LOC_TYPEDEF - && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE - && (TYPE_CODE (SYMBOL_TYPE (sym)) == - TYPE_CODE (*type)) - && STREQ (SYMBOL_NAME (sym), typename)) - { - memcpy (*type, SYMBOL_TYPE (sym), - sizeof (struct type)); - } - } - } - } - } - break; - - case TYPE_CODE_ARRAY: - { - /* This is a kludge which is here for historical reasons - because I suspect that check_stub_type does not get - called everywhere it needs to be called for arrays. Even - with this kludge, those places are broken for the case - where the stub type is defined in another compilation - unit, but this kludge at least deals with it for the case - in which it is the same compilation unit. - - Don't try to do this by calling check_stub_type; it might - cause symbols to be read in lookup_symbol, and the symbol - reader is not reentrant. */ - - struct type *range_type; - int lower, upper; - - if (TYPE_LENGTH (*type) != 0) /* Better be unknown */ - goto badtype; - if (TYPE_NFIELDS (*type) != 1) - goto badtype; - range_type = TYPE_FIELD_TYPE (*type, 0); - if (TYPE_CODE (range_type) != TYPE_CODE_RANGE) - goto badtype; - - /* Now recompute the length of the array type, based on its - number of elements and the target type's length. */ - lower = TYPE_FIELD_BITPOS (range_type, 0); - upper = TYPE_FIELD_BITPOS (range_type, 1); - TYPE_LENGTH (*type) = (upper - lower + 1) - * TYPE_LENGTH (TYPE_TARGET_TYPE (*type)); - - /* If the target type is not a stub, we could be clearing - TYPE_FLAG_TARGET_STUB for *type. */ - } - break; - - default: - badtype: - { - static struct complaint msg = {"\ -GDB internal error. cleanup_undefined_types with bad type %d.", 0, 0}; - complain (&msg, TYPE_CODE (*type)); - } - break; - } - } - - undef_types_length = 0; -} - -/* Scan through all of the global symbols defined in the object file, - assigning values to the debugging symbols that need to be assigned - to. Get these symbols from the minimal symbol table. */ - -void -scan_file_globals (objfile) - struct objfile *objfile; -{ - int hash; - struct minimal_symbol *msymbol; - struct symbol *sym, *prev; - - if (objfile->msymbols == 0) /* Beware the null file. */ - return; - - for (msymbol = objfile -> msymbols; SYMBOL_NAME (msymbol) != NULL; msymbol++) - { - QUIT; - - prev = NULL; - - /* 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;) - { - if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] && - STREQ(SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1)) - { - /* 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_CLASS (sym) == LOC_BLOCK) - { - fix_common_block (sym, SYMBOL_VALUE_ADDRESS (msymbol)); - } - else - { - SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msymbol); - } - - SYMBOL_SECTION (sym) = SYMBOL_SECTION (msymbol); - - if (prev) - { - sym = SYMBOL_VALUE_CHAIN (prev); - } - else - { - sym = global_sym_chain[hash]; - } - } - else - { - prev = sym; - sym = SYMBOL_VALUE_CHAIN (sym); - } - } - } -} - -/* 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 -stabsread_init () -{ -} - -/* 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). */ - -void -stabsread_new_init () -{ - /* Empty the hash table of global syms looking for values. */ - memset (global_sym_chain, 0, sizeof (global_sym_chain)); -} - -/* Initialize anything that needs initializing at the same time as - start_symtab() is called. */ - -void start_stabs () -{ - global_stabs = NULL; /* AIX COFF */ - /* Leave FILENUM of 0 free for builtin types and this file's types. */ - n_this_object_header_files = 1; - type_vector_length = 0; - type_vector = (struct type **) 0; - - /* FIXME: If common_block_name is not already NULL, we should complain(). */ - common_block_name = NULL; - - os9k_stabs = 0; -} - -/* Call after end_symtab() */ - -void end_stabs () -{ - if (type_vector) - { - free ((char *) type_vector); - } - type_vector = 0; - type_vector_length = 0; - previous_stab_code = 0; -} - -void -finish_global_stabs (objfile) - struct objfile *objfile; -{ - if (global_stabs) - { - patch_block_stabs (global_symbols, global_stabs, objfile); - free ((PTR) global_stabs); - global_stabs = NULL; - } -} - -/* Initializer for this module */ - -void -_initialize_stabsread () -{ - undef_types_allocated = 20; - undef_types_length = 0; - undef_types = (struct type **) - xmalloc (undef_types_allocated * sizeof (struct type *)); -} diff --git a/gnu/usr.bin/gdb/gdb/stabsread.h b/gnu/usr.bin/gdb/gdb/stabsread.h deleted file mode 100644 index 20859d6..0000000 --- a/gnu/usr.bin/gdb/gdb/stabsread.h +++ /dev/null @@ -1,212 +0,0 @@ -/* Include file for stabs debugging format support functions. - Copyright 1986-1991, 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. */ - -/* Definitions, prototypes, etc for stabs debugging format support - functions. - - 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 - -/* Convert stab register number (from `r' declaration) to a gdb REGNUM. */ - -#ifndef STAB_REG_TO_REGNUM -#define STAB_REG_TO_REGNUM(VALUE) (VALUE) -#endif - -/* Hash table of global symbols whose values are not known yet. - They are chained thru the SYMBOL_VALUE_CHAIN, since we don't - have the correct data for that slot yet. - - The use of the LOC_BLOCK code in this chain is nonstandard-- - it refers to a FORTRAN common block rather than the usual meaning, and - the such LOC_BLOCK symbols use their fields in nonstandard ways. */ - -EXTERN struct symbol *global_sym_chain[HASHSIZE]; - -extern void common_block_start PARAMS ((char *, struct objfile *)); -extern void common_block_end PARAMS ((struct objfile *)); - -/* Kludge for xcoffread.c */ - -struct pending_stabs -{ - int count; - int length; - char *stab[1]; -}; - -EXTERN struct pending_stabs *global_stabs; - -/* The type code that process_one_symbol saw on its previous invocation. - Used to detect pairs of N_SO symbols. */ - -EXTERN int previous_stab_code; - -/* Support for Sun changes to dbx symbol format */ - -/* For each identified header file, we have a table of types defined - in that header file. - - header_files maps header file names to their type tables. - It is a vector of n_header_files elements. - Each element describes one header file. - It contains a vector of types. - - Sometimes it can happen that the same header file produces - different results when included in different places. - This can result from conditionals or from different - things done before including the file. - When this happens, there are multiple entries for the file in this table, - one entry for each distinct set of results. - The entries are distinguished by the INSTANCE field. - The INSTANCE field appears in the N_BINCL and N_EXCL symbol table and is - used to match header-file references to their corresponding data. */ - -struct header_file -{ - - /* Name of header file */ - - char *name; - - /* Numeric code distinguishing instances of one header file that produced - different results when included. It comes from the N_BINCL or N_EXCL. */ - - int instance; - - /* Pointer to vector of types */ - - struct type **vector; - - /* Allocated length (# elts) of that vector */ - - int length; - -}; - -EXTERN struct header_file *header_files; - -EXTERN int n_header_files; - -EXTERN int 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 - (FILENUM,TYPENUM) where FILENUM is the number of the header file - 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, - and not to any header file. FILENUM != 1 is interpreted by looking it up - in the following table, which contains indices in header_files. */ - -EXTERN int *this_object_header_files; - -EXTERN int n_this_object_header_files; - -EXTERN int n_allocated_this_object_header_files; - -extern struct complaint unknown_symtype_complaint; -extern struct complaint unknown_symchar_complaint; - -extern struct type * -read_type PARAMS ((char **, struct objfile *)); - -extern void -cleanup_undefined_types PARAMS ((void)); - -extern struct type ** -dbx_lookup_type PARAMS ((int [2])); - -extern long -read_number PARAMS ((char **, int)); - -extern void -add_undefined_type PARAMS ((struct type *)); - -extern struct symbol * -define_symbol PARAMS ((CORE_ADDR, char *, int, int, struct objfile *)); - -extern void -stabsread_init PARAMS ((void)); - -extern void -stabsread_new_init PARAMS ((void)); - -extern void -start_stabs PARAMS ((void)); - -extern void -end_stabs PARAMS ((void)); - -extern void -finish_global_stabs PARAMS ((struct objfile *objfile)); - -EXTERN int os9k_stabs; - -/* Functions exported by dbxread.c. These are not in stabsread.h because - they are only used by some stabs readers. */ - -extern struct partial_symtab * -start_psymtab PARAMS ((struct objfile *, struct section_offsets *, char *, - CORE_ADDR, int, struct partial_symbol *, - struct partial_symbol *)); - -extern struct partial_symtab * -end_psymtab PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR, - struct partial_symtab **, int)); - -extern void -process_one_symbol PARAMS ((int, int, CORE_ADDR, char *, - struct section_offsets *, struct objfile *)); - -extern void elfstab_build_psymtabs - PARAMS ((struct objfile *objfile, - struct section_offsets *section_offsets, - int mainline, - file_ptr staboff, unsigned int stabsize, - file_ptr stabstroffset, - unsigned int stabstrsize)); - -extern void coffstab_build_psymtabs - PARAMS ((struct objfile *objfile, - struct section_offsets *section_offsets, - int mainline, - file_ptr staboff, unsigned int stabsize, - file_ptr stabstroffset, - unsigned int stabstrsize)); - -extern void stabsect_build_psymtabs - PARAMS ((struct objfile *objfile, - struct section_offsets *section_offsets, - int mainline, - char *stab_name, - char *stabstr_name, - char *text_name)); - -extern void elfstab_offset_sections PARAMS ((struct objfile *, - struct partial_symtab *)); - -#undef EXTERN diff --git a/gnu/usr.bin/gdb/gdb/stack.c b/gnu/usr.bin/gdb/gdb/stack.c deleted file mode 100644 index 6eb56e4..0000000 --- a/gnu/usr.bin/gdb/gdb/stack.c +++ /dev/null @@ -1,1482 +0,0 @@ -/* Print and select stack frames for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 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. */ - -#include "defs.h" -#include "value.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "language.h" -#include "frame.h" -#include "gdbcmd.h" -#include "gdbcore.h" -#include "target.h" -#include "breakpoint.h" -#include "demangle.h" -#include "inferior.h" -#include "annotate.h" - -static void -return_command PARAMS ((char *, int)); - -static void -down_command PARAMS ((char *, int)); - -static void -down_silently_command PARAMS ((char *, int)); - -static void -up_command PARAMS ((char *, int)); - -static void -up_silently_command PARAMS ((char *, int)); - -static 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 ((FRAME, GDB_FILE *)); - -static void -catch_info PARAMS ((char *, int)); - -static void -locals_info PARAMS ((char *, int)); - -static void -print_frame_label_vars PARAMS ((FRAME, int, GDB_FILE *)); - -static void -print_frame_local_vars PARAMS ((FRAME, GDB_FILE *)); - -static int -print_block_frame_labels PARAMS ((struct block *, int *, GDB_FILE *)); - -static int -print_block_frame_locals PARAMS ((struct block *, FRAME, GDB_FILE *)); - -static void -backtrace_command PARAMS ((char *, int)); - -static FRAME -parse_frame_specification PARAMS ((char *)); - -static void -frame_info PARAMS ((char *, int)); - - -extern int addressprint; /* Print addresses, or stay symbolic only? */ -extern int info_verbose; /* Verbosity of symbol reading msgs */ -extern int lines_to_list; /* # of lines "list" command shows by default */ - -/* The "selected" stack frame is used by default for local and arg access. - May be zero, for no selected frame. */ - -FRAME selected_frame; - -/* Level of the selected frame: - 0 for innermost, 1 for its caller, ... - or -1 for frame specified by address with no defined level. */ - -int selected_frame_level; - -/* Zero means do things normally; we are interacting directly with the - user. One means print the full filename and linenumber when a - frame is printed, and do so in a format emacs18/emacs19.22 can - parse. Two means print similar annotations, but in many more - cases and in a slightly different syntax. */ - -int annotation_level = 0; - - -struct print_stack_frame_args { - struct frame_info *fi; - int level; - int source; - int args; -}; - -static int print_stack_frame_stub PARAMS ((char *)); - -/* 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; - print_frame_info (p->fi, p->level, p->source, p->args); - return 0; -} - -/* Print a stack frame briefly. FRAME should be the frame id - 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 (frame, level, source) - FRAME frame; - int level; - int source; -{ - struct print_stack_frame_args args; - - args.fi = get_frame_info (frame); - args.level = level; - args.source = source; - args.args = 1; - - catch_errors (print_stack_frame_stub, (char *)&args, "", RETURN_MASK_ERROR); -} - -struct print_args_args { - struct symbol *func; - struct frame_info *fi; -}; - -static int print_args_stub PARAMS ((char *)); - -/* Pass the args the way catch_errors wants them. */ -static int -print_args_stub (args) - char *args; -{ - int numargs; - struct print_args_args *p = (struct print_args_args *)args; - FRAME_NUM_ARGS (numargs, (p->fi)); - print_frame_args (p->func, p->fi, numargs, gdb_stdout); - 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. */ -void -print_frame_info (fi, level, source, args) - struct frame_info *fi; - register int level; - int source; - int args; -{ - struct symtab_and_line sal; - struct symbol *func; - register char *funname = 0; - enum language funlang = language_unknown; - -#if 0 - char buf[MAX_REGISTER_RAW_SIZE]; - CORE_ADDR sp; - - /* On the 68k, this spends too much time in m68k_find_saved_regs. */ - - /* Get the value of SP_REGNUM relative to the frame. */ - get_saved_register (buf, (int *)NULL, (CORE_ADDR *)NULL, - FRAME_INFO_ID (fi), SP_REGNUM, (enum lval_type *)NULL); - sp = extract_address (buf, REGISTER_RAW_SIZE (SP_REGNUM)); - - /* This is not a perfect test, because if a function alloca's some - memory, puts some code there, and then jumps into it, then the test - will succeed even though there is no call dummy. Probably best is - to check for a bp_call_dummy breakpoint. */ - if (PC_IN_CALL_DUMMY (fi->pc, sp, fi->frame)) -#else - if (frame_in_dummy (fi)) -#endif - { - annotate_frame_begin (level == -1 ? 0 : level, fi->pc); - - /* Do this regardless of SOURCE because we don't have any source - to list for this frame. */ - if (level >= 0) - printf_filtered ("#%-2d ", level); - annotate_function_call (); - printf_filtered ("\n"); - annotate_frame_end (); - return; - } - if (fi->signal_handler_caller) - { - annotate_frame_begin (level == -1 ? 0 : level, fi->pc); - - /* Do this regardless of SOURCE because we don't have any source - to list for this frame. */ - if (level >= 0) - printf_filtered ("#%-2d ", level); - annotate_signal_handler_caller (); - printf_filtered ("\n"); - annotate_frame_end (); - return; - } - - /* If fi is not the innermost frame, that normally means that fi->pc - points to *after* the call instruction, and we want to get the line - containing the call, never the next line. But if the next frame is - a signal_handler_caller or a dummy frame, then the next frame was - not entered as the result of a call, and we want to get the line - containing fi->pc. */ - sal = - find_pc_line (fi->pc, - fi->next != NULL - && !fi->next->signal_handler_caller - && !frame_in_dummy (fi->next)); - - func = find_pc_function (fi->pc); - if (func) - { - /* In certain pathological cases, the symtabs give the wrong - function (when we are in the first function in a file which - is compiled without debugging symbols, the previous function - is compiled with debugging symbols, and the "foo.o" symbol - that is supposed to tell us where the file with debugging symbols - ends has been truncated by ar because it is longer than 15 - characters). This also occurs if the user uses asm() to create - a function but not stabs for it (in a file compiled -g). - - So look in the minimal symbol tables as well, and if it comes - up with a larger address for the function use that instead. - I don't think this can ever cause any problems; there shouldn't - be any minimal symbols in the middle of a function; if this is - ever changed many parts of GDB will need to be changed (and we'll - create a find_pc_minimal_function or some such). */ - - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); - if (msymbol != NULL - && (SYMBOL_VALUE_ADDRESS (msymbol) - > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) - { -#if 0 - /* There is no particular reason to think the line number - information is wrong. Someone might have just put in - a label with asm() but left the line numbers alone. */ - /* In this case we have no way of knowing the source file - and line number, so don't print them. */ - sal.symtab = 0; -#endif - /* We also don't know anything about the function besides - its address and name. */ - func = 0; - funname = SYMBOL_NAME (msymbol); - funlang = SYMBOL_LANGUAGE (msymbol); - } - else - { - funname = SYMBOL_NAME (func); - funlang = SYMBOL_LANGUAGE (func); - } - } - else - { - register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); - if (msymbol != NULL) - { - funname = SYMBOL_NAME (msymbol); - funlang = SYMBOL_LANGUAGE (msymbol); - } - } - - if (source >= 0 || !sal.symtab) - { - annotate_frame_begin (level == -1 ? 0 : level, fi->pc); - - if (level >= 0) - printf_filtered ("#%-2d ", level); - if (addressprint) - if (fi->pc != sal.pc || !sal.symtab) - { - annotate_frame_address (); - print_address_numeric (fi->pc, 1, gdb_stdout); - annotate_frame_address_end (); - printf_filtered (" in "); - } - annotate_frame_function_name (); - fprintf_symbol_filtered (gdb_stdout, funname ? funname : "??", funlang, - DMGL_ANSI); - wrap_here (" "); - annotate_frame_args (); - fputs_filtered (" (", gdb_stdout); - if (args) - { - struct print_args_args args; - args.fi = fi; - args.func = func; - catch_errors (print_args_stub, (char *)&args, "", RETURN_MASK_ERROR); - } - printf_filtered (")"); - if (sal.symtab && sal.symtab->filename) - { - annotate_frame_source_begin (); - wrap_here (" "); - printf_filtered (" at "); - annotate_frame_source_file (); - printf_filtered ("%s", sal.symtab->filename); - annotate_frame_source_file_end (); - printf_filtered (":"); - annotate_frame_source_line (); - printf_filtered ("%d", sal.line); - annotate_frame_source_end (); - } - -#ifdef PC_LOAD_SEGMENT - /* If we couldn't print out function name but if can figure out what - load segment this pc value is from, at least print out some info - about its load segment. */ - if (!funname) - { - annotate_frame_where (); - wrap_here (" "); - printf_filtered (" from %s", PC_LOAD_SEGMENT (fi->pc)); - } -#endif - printf_filtered ("\n"); - } - - if ((source != 0) && sal.symtab) - { - int done = 0; - int mid_statement = source < 0 && fi->pc != sal.pc; - if (annotation_level) - done = identify_source_line (sal.symtab, sal.line, mid_statement, - fi->pc); - if (!done) - { - if (addressprint && mid_statement) - { - print_address_numeric (fi->pc, 1, gdb_stdout); - printf_filtered ("\t"); - } - print_source_lines (sal.symtab, sal.line, sal.line + 1, 0); - } - current_source_line = max (sal.line - lines_to_list/2, 1); - } - if (source != 0) - set_default_breakpoint (1, fi->pc, sal.symtab, sal.line); - - annotate_frame_end (); - - gdb_flush (gdb_stdout); -} - -/* - * 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 FRAME -parse_frame_specification (frame_exp) - char *frame_exp; -{ - int numargs = 0; -#define MAXARGS 4 - CORE_ADDR args[MAXARGS]; - - if (frame_exp) - { - char *addr_string, *p; - struct cleanup *tmp_cleanup; - - while (*frame_exp == ' ') frame_exp++; - - while (*frame_exp) - { - if (numargs > MAXARGS) - error ("Too many args in frame specification"); - /* Parse an argument. */ - for (p = frame_exp; *p && *p != ' '; p++) - ; - addr_string = savestring(frame_exp, p - frame_exp); - - { - tmp_cleanup = make_cleanup (free, addr_string); - args[numargs++] = parse_and_eval_address (addr_string); - do_cleanups (tmp_cleanup); - } - - /* Skip spaces, move to possible next arg. */ - while (*p == ' ') p++; - frame_exp = p; - } - } - - switch (numargs) - { - case 0: - if (selected_frame == NULL) - error ("No selected frame."); - return selected_frame; - /* NOTREACHED */ - case 1: - { - int level = args[0]; - FRAME fid = find_relative_frame (get_current_frame (), &level); - FRAME tfid; - - if (level == 0) - /* find_relative_frame was successful */ - return fid; - - /* If SETUP_ARBITRARY_FRAME is defined, then frame specifications - take at least 2 addresses. It is important to detect this case - here so that "frame 100" does not give a confusing error message - like "frame specification requires two addresses". This of course - does not solve the "frame 100" problem for machines on which - a frame specification can be made with one address. To solve - that, we need a new syntax for a specifying a frame by address. - I think the cleanest syntax is $frame(0x45) ($frame(0x23,0x45) for - two args, etc.), but people might think that is too much typing, - so I guess *0x23,0x45 would be a possible alternative (commas - really should be used instead of spaces to delimit; using spaces - normally works in an expression). */ -#ifdef SETUP_ARBITRARY_FRAME - error ("No frame %d", args[0]); -#endif - - /* If (s)he specifies the frame with an address, he deserves what - (s)he gets. Still, give the highest one that matches. */ - - for (fid = get_current_frame (); - fid && FRAME_FP (fid) != args[0]; - fid = get_prev_frame (fid)) - ; - - if (fid) - while ((tfid = get_prev_frame (fid)) && - (FRAME_FP (tfid) == args[0])) - fid = tfid; - - /* We couldn't identify the frame as an existing frame, but - perhaps we can create one with a single argument. */ - } - - default: -#ifdef SETUP_ARBITRARY_FRAME - return SETUP_ARBITRARY_FRAME (numargs, args); -#else - /* Usual case. Do it here rather than have everyone supply - a SETUP_ARBITRARY_FRAME that does this. */ - if (numargs == 1) - return create_new_frame (args[0], 0); - error ("Too many args in frame specification"); -#endif - /* NOTREACHED */ - } - /* NOTREACHED */ -} - -/* FRAME_ARGS_ADDRESS_CORRECT is just like FRAME_ARGS_ADDRESS except - that if it is unsure about the answer, it returns 0 - instead of guessing (this happens on the VAX and i960, for example). - - On most machines, we never have to guess about the args address, - so FRAME_ARGS_ADDRESS{,_CORRECT} are the same. */ -#if !defined (FRAME_ARGS_ADDRESS_CORRECT) -#define FRAME_ARGS_ADDRESS_CORRECT FRAME_ARGS_ADDRESS -#endif - -/* Print verbosely the selected frame or the frame at address ADDR. - This means absolutely all information in the frame is printed. */ - -static void -frame_info (addr_exp, from_tty) - char *addr_exp; - int from_tty; -{ - FRAME frame; - struct frame_info *fi; - struct frame_saved_regs fsr; - struct symtab_and_line sal; - struct symbol *func; - struct symtab *s; - FRAME calling_frame; - int i, count, numregs; - char *funname = 0; - enum language funlang = language_unknown; - - if (!target_has_stack) - error ("No stack."); - - frame = parse_frame_specification (addr_exp); - if (!frame) - error ("Invalid frame specified."); - - fi = get_frame_info (frame); - sal = find_pc_line (fi->pc, - fi->next != NULL - && !fi->next->signal_handler_caller - && !frame_in_dummy (fi->next)); - func = get_frame_function (frame); - s = find_pc_symtab(fi->pc); - if (func) - { - funname = SYMBOL_NAME (func); - funlang = SYMBOL_LANGUAGE (func); - } - else - { - register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc); - if (msymbol != NULL) - { - funname = SYMBOL_NAME (msymbol); - funlang = SYMBOL_LANGUAGE (msymbol); - } - } - calling_frame = get_prev_frame (frame); - - if (!addr_exp && selected_frame_level >= 0) - { - printf_filtered ("Stack level %d, frame at ", selected_frame_level); - print_address_numeric (FRAME_FP(frame), 1, gdb_stdout); - printf_filtered (":\n"); - } - else - { - printf_filtered ("Stack frame at "); - print_address_numeric (FRAME_FP(frame), 1, gdb_stdout); - printf_filtered (":\n"); - } - printf_filtered (" %s = ", - reg_names[PC_REGNUM]); - print_address_numeric (fi->pc, 1, gdb_stdout); - - wrap_here (" "); - if (funname) - { - printf_filtered (" in "); - fprintf_symbol_filtered (gdb_stdout, funname, funlang, - DMGL_ANSI | DMGL_PARAMS); - } - wrap_here (" "); - if (sal.symtab) - printf_filtered (" (%s:%d)", sal.symtab->filename, sal.line); - puts_filtered ("; "); - wrap_here (" "); - printf_filtered ("saved %s ", reg_names[PC_REGNUM]); - print_address_numeric (FRAME_SAVED_PC (frame), 1, gdb_stdout); - printf_filtered ("\n"); - - { - int frameless = 0; -#ifdef FRAMELESS_FUNCTION_INVOCATION - FRAMELESS_FUNCTION_INVOCATION (fi, frameless); -#endif - if (frameless) - printf_filtered (" (FRAMELESS),"); - } - - if (calling_frame) - { - printf_filtered (" called by frame at "); - print_address_numeric (FRAME_FP (calling_frame), 1, gdb_stdout); - } - if (fi->next && calling_frame) - puts_filtered (","); - wrap_here (" "); - if (fi->next) - { - printf_filtered (" caller of frame at "); - print_address_numeric (fi->next->frame, 1, gdb_stdout); - } - if (fi->next || calling_frame) - puts_filtered ("\n"); - if (s) - printf_filtered (" source language %s.\n", language_str (s->language)); - -#ifdef PRINT_EXTRA_FRAME_INFO - PRINT_EXTRA_FRAME_INFO (fi); -#endif - - { - /* Address of the argument list for this frame, or 0. */ - CORE_ADDR arg_list = FRAME_ARGS_ADDRESS_CORRECT (fi); - /* Number of args for this frame, or -1 if unknown. */ - int numargs; - - if (arg_list == 0) - printf_filtered (" Arglist at unknown address.\n"); - else - { - printf_filtered (" Arglist at "); - print_address_numeric (arg_list, 1, gdb_stdout); - printf_filtered (","); - - FRAME_NUM_ARGS (numargs, fi); - if (numargs < 0) - puts_filtered (" args: "); - else if (numargs == 0) - puts_filtered (" no args."); - else if (numargs == 1) - puts_filtered (" 1 arg: "); - else - printf_filtered (" %d args: ", numargs); - print_frame_args (func, fi, numargs, gdb_stdout); - puts_filtered ("\n"); - } - } - { - /* Address of the local variables for this frame, or 0. */ - CORE_ADDR arg_list = FRAME_LOCALS_ADDRESS (fi); - - if (arg_list == 0) - printf_filtered (" Locals at unknown address,"); - else - { - printf_filtered (" Locals at "); - print_address_numeric (arg_list, 1, gdb_stdout); - printf_filtered (","); - } - } - -#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. */ - puts_filtered ("\n"); -#endif /* Have FRAME_FIND_SAVED_REGS. */ -} - -#if 0 -/* Set a limit on the number of frames printed by default in a - backtrace. */ - -static int backtrace_limit; - -static void -set_backtrace_limit_command (count_exp, from_tty) - char *count_exp; - int from_tty; -{ - int count = parse_and_eval_address (count_exp); - - if (count < 0) - error ("Negative argument not meaningful as backtrace limit."); - - backtrace_limit = count; -} - -static void -backtrace_limit_info (arg, from_tty) - char *arg; - int from_tty; -{ - if (arg) - error ("\"Info backtrace-limit\" takes no arguments."); - - printf_unfiltered ("Backtrace limit: %d.\n", backtrace_limit); -} -#endif - -/* Print briefly all stack frames or just the innermost COUNT frames. */ - -static void -backtrace_command (count_exp, from_tty) - char *count_exp; - int from_tty; -{ - struct frame_info *fi; - register int count; - register FRAME frame; - register int i; - register FRAME trailing; - register int trailing_level; - - if (!target_has_stack) - error ("No stack."); - - /* The following code must do two things. First, it must - set the variable TRAILING to the frame from which we should start - printing. Second, it must set the variable count to the number - of frames which we should print, or -1 if all of them. */ - trailing = get_current_frame (); - trailing_level = 0; - if (count_exp) - { - count = parse_and_eval_address (count_exp); - if (count < 0) - { - FRAME current; - - count = -count; - - current = trailing; - while (current && count--) - { - QUIT; - current = get_prev_frame (current); - } - - /* Will stop when CURRENT reaches the top of the stack. TRAILING - will be COUNT below it. */ - while (current) - { - QUIT; - trailing = get_prev_frame (trailing); - current = get_prev_frame (current); - trailing_level++; - } - - count = -1; - } - } - else - count = -1; - - if (info_verbose) - { - struct partial_symtab *ps; - - /* Read in symbols for all of the frames. Need to do this in - a separate pass so that "Reading in symbols for xxx" messages - don't screw up the appearance of the backtrace. Also - if people have strong opinions against reading symbols for - backtrace this may have to be an option. */ - i = count; - for (frame = trailing; - frame != NULL && i--; - frame = get_prev_frame (frame)) - { - QUIT; - fi = get_frame_info (frame); - ps = find_pc_psymtab (fi->pc); - if (ps) - PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in */ - } - } - - for (i = 0, frame = trailing; - frame && count--; - i++, frame = get_prev_frame (frame)) - { - QUIT; - fi = get_frame_info (frame); - - /* Don't use print_stack_frame; if an error() occurs it probably - 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); - } - - /* If we've stopped before the end, mention that. */ - if (frame && from_tty) - printf_filtered ("(More stack frames follow...)\n"); -} - -/* 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, frame, stream) - struct block *b; - register FRAME frame; - register GDB_FILE *stream; -{ - int nsyms; - register int i; - register struct symbol *sym; - register int values_printed = 0; - - nsyms = BLOCK_NSYMS (b); - - for (i = 0; i < nsyms; i++) - { - sym = BLOCK_SYM (b, i); - switch (SYMBOL_CLASS (sym)) - { - case LOC_LOCAL: - case LOC_REGISTER: - case LOC_STATIC: - case LOC_BASEREG: - values_printed = 1; - fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream); - fputs_filtered (" = ", stream); - print_variable_value (sym, frame, stream); - fprintf_filtered (stream, "\n"); - break; - - default: - /* Ignore symbols which are not locals. */ - break; - } - } - return values_printed; -} - -/* Same, but print labels. */ - -static int -print_block_frame_labels (b, have_default, stream) - struct block *b; - int *have_default; - register GDB_FILE *stream; -{ - int nsyms; - register int i; - register struct symbol *sym; - register int values_printed = 0; - - nsyms = BLOCK_NSYMS (b); - - for (i = 0; i < nsyms; i++) - { - sym = BLOCK_SYM (b, i); - if (STREQ (SYMBOL_NAME (sym), "default")) - { - if (*have_default) - continue; - *have_default = 1; - } - if (SYMBOL_CLASS (sym) == LOC_LABEL) - { - struct symtab_and_line sal; - sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0); - values_printed = 1; - fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream); - if (addressprint) - { - fprintf_filtered (stream, " "); - print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, stream); - } - fprintf_filtered (stream, " in file %s, line %d\n", - sal.symtab->filename, sal.line); - } - } - return values_printed; -} - -/* Print on STREAM all the local variables in frame FRAME, - including all the blocks active in that frame - at its current pc. - - Returns 1 if the job was done, - or 0 if nothing was printed because we have no info - on the function running in FRAME. */ - -static void -print_frame_local_vars (frame, stream) - register FRAME frame; - register GDB_FILE *stream; -{ - register struct block *block = get_frame_block (frame); - register int values_printed = 0; - - if (block == 0) - { - fprintf_filtered (stream, "No symbol table info available.\n"); - return; - } - - while (block != 0) - { - if (print_block_frame_locals (block, frame, stream)) - values_printed = 1; - /* After handling the function's top-level block, stop. - Don't continue to its superblock, the block of - per-file symbols. */ - if (BLOCK_FUNCTION (block)) - break; - block = BLOCK_SUPERBLOCK (block); - } - - if (!values_printed) - { - fprintf_filtered (stream, "No locals.\n"); - } -} - -/* Same, but print labels. */ - -static void -print_frame_label_vars (frame, this_level_only, stream) - register FRAME frame; - int this_level_only; - register GDB_FILE *stream; -{ - register struct blockvector *bl; - register struct block *block = get_frame_block (frame); - register int values_printed = 0; - int index, have_default = 0; - char *blocks_printed; - struct frame_info *fi = get_frame_info (frame); - CORE_ADDR pc = fi->pc; - - if (block == 0) - { - fprintf_filtered (stream, "No symbol table info available.\n"); - return; - } - - bl = blockvector_for_pc (BLOCK_END (block) - 4, &index); - blocks_printed = (char *) alloca (BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); - memset (blocks_printed, 0, BLOCKVECTOR_NBLOCKS (bl) * sizeof (char)); - - while (block != 0) - { - CORE_ADDR end = BLOCK_END (block) - 4; - int last_index; - - if (bl != blockvector_for_pc (end, &index)) - error ("blockvector blotch"); - if (BLOCKVECTOR_BLOCK (bl, index) != block) - error ("blockvector botch"); - last_index = BLOCKVECTOR_NBLOCKS (bl); - index += 1; - - /* Don't print out blocks that have gone by. */ - while (index < last_index - && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < pc) - index++; - - while (index < last_index - && BLOCK_END (BLOCKVECTOR_BLOCK (bl, index)) < end) - { - if (blocks_printed[index] == 0) - { - if (print_block_frame_labels (BLOCKVECTOR_BLOCK (bl, index), &have_default, stream)) - values_printed = 1; - blocks_printed[index] = 1; - } - index++; - } - if (have_default) - return; - if (values_printed && this_level_only) - return; - - /* After handling the function's top-level block, stop. - Don't continue to its superblock, the block of - per-file symbols. */ - if (BLOCK_FUNCTION (block)) - break; - block = BLOCK_SUPERBLOCK (block); - } - - if (!values_printed && !this_level_only) - { - fprintf_filtered (stream, "No catches.\n"); - } -} - -/* ARGSUSED */ -static 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); -} - -static void -catch_info (ignore, from_tty) - char *ignore; - int from_tty; -{ - if (!selected_frame) - error ("No frame selected."); - print_frame_label_vars (selected_frame, 0, gdb_stdout); -} - -static void -print_frame_arg_vars (frame, stream) - register FRAME frame; - register GDB_FILE *stream; -{ - struct symbol *func = get_frame_function (frame); - register struct block *b; - int nsyms; - register int i; - register struct symbol *sym, *sym2; - register int values_printed = 0; - - if (func == 0) - { - fprintf_filtered (stream, "No symbol table info available.\n"); - return; - } - - b = SYMBOL_BLOCK_VALUE (func); - nsyms = BLOCK_NSYMS (b); - - for (i = 0; i < nsyms; i++) - { - sym = BLOCK_SYM (b, i); - switch (SYMBOL_CLASS (sym)) - { - case LOC_ARG: - case LOC_LOCAL_ARG: - case LOC_REF_ARG: - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_BASEREG_ARG: - values_printed = 1; - fputs_filtered (SYMBOL_SOURCE_NAME (sym), stream); - fputs_filtered (" = ", stream); - - /* We have to look up the symbol because arguments can have - two entries (one a parameter, one a local) and the one we - want is the local, which lookup_symbol will find for us. - This includes gcc1 (not gcc2) on the sparc when passing a - small structure and gcc2 when the argument type is float - and it is passed as a double and converted to float by - the prologue (in the latter case the type of the LOC_ARG - symbol is double and the type of the LOC_LOCAL symbol is - float). There are also LOC_ARG/LOC_REGISTER pairs which - are not combined in symbol-reading. */ - - sym2 = lookup_symbol (SYMBOL_NAME (sym), - b, VAR_NAMESPACE, (int *)NULL, (struct symtab **)NULL); - print_variable_value (sym2, frame, stream); - fprintf_filtered (stream, "\n"); - break; - - default: - /* Don't worry about things which aren't arguments. */ - break; - } - } - - if (!values_printed) - { - fprintf_filtered (stream, "No arguments.\n"); - } -} - -static void -args_info (ignore, from_tty) - char *ignore; - int from_tty; -{ - if (!selected_frame) - error ("No frame selected."); - print_frame_arg_vars (selected_frame, gdb_stdout); -} - -/* Select frame FRAME, and note that its stack level is LEVEL. - LEVEL may be -1 if an actual level number is not known. */ - -void -select_frame (frame, level) - FRAME frame; - int level; -{ - register struct symtab *s; - - selected_frame = frame; - selected_frame_level = level; - - /* Ensure that symbols for this frame are read in. Also, determine the - source language of this frame, and switch to it if desired. */ - if (frame) - { - s = find_pc_symtab (get_frame_info (frame)->pc); - if (s - && s->language != current_language->la_language - && s->language != language_unknown - && language_mode == language_mode_auto) { - set_language(s->language); - } - } -} - -/* Store the selected frame and its level into *FRAMEP and *LEVELP. - If there is no selected frame, *FRAMEP is set to NULL. */ - -void -record_selected_frame (frameaddrp, levelp) - FRAME_ADDR *frameaddrp; - int *levelp; -{ - *frameaddrp = selected_frame ? FRAME_FP (selected_frame) : 0; - *levelp = selected_frame_level; -} - -/* Return the symbol-block in which the selected frame is executing. - Can return zero under various legitimate circumstances. */ - -struct block * -get_selected_block () -{ - if (!target_has_stack) - return 0; - - if (!selected_frame) - return get_current_block (); - return get_frame_block (selected_frame); -} - -/* Find a frame a certain number of levels away from FRAME. - LEVEL_OFFSET_PTR points to an int containing the number of levels. - Positive means go to earlier frames (up); negative, the reverse. - The int that contains the number of levels is counted toward - zero as the frames for those levels are found. - If the top or bottom frame is reached, that frame is returned, - but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates - how much farther the original request asked to go. */ - -FRAME -find_relative_frame (frame, level_offset_ptr) - register FRAME frame; - register int* level_offset_ptr; -{ - register FRAME prev; - register FRAME frame1; - - /* Going up is simple: just do get_prev_frame enough times - or until initial frame is reached. */ - while (*level_offset_ptr > 0) - { - prev = get_prev_frame (frame); - if (prev == 0) - break; - (*level_offset_ptr)--; - frame = prev; - } - /* Going down is just as simple. */ - if (*level_offset_ptr < 0) - { - while (*level_offset_ptr < 0) { - frame1 = get_next_frame (frame); - if (!frame1) - break; - frame = frame1; - (*level_offset_ptr)++; - } - } - return frame; -} - -/* The "select_frame" command. With no arg, NOP. - With arg LEVEL_EXP, select the frame at level LEVEL if it is a - valid level. Otherwise, treat level_exp as an address expression - and select it. See parse_frame_specification for more info on proper - frame expressions. */ - -/* ARGSUSED */ -static void -select_frame_command (level_exp, from_tty) - char *level_exp; - int from_tty; -{ - register FRAME frame, frame1; - unsigned int level = 0; - - if (!target_has_stack) - error ("No stack."); - - frame = parse_frame_specification (level_exp); - - /* Try to figure out what level this frame is. But if there is - no current stack, don't error out -- let the user set one. */ - frame1 = 0; - if (get_current_frame()) { - for (frame1 = get_prev_frame (0); - frame1 && frame1 != frame; - frame1 = get_prev_frame (frame1)) - level++; - } - - if (!frame1) - level = 0; - - select_frame (frame, level); -} - -/* The "frame" command. With no arg, print selected frame briefly. - With arg, behaves like select_frame and then prints the selected - frame. */ - -static 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); -} - -/* 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) - char *count_exp; - int from_tty; -{ - register FRAME frame; - int count = 1, count1; - if (count_exp) - count = parse_and_eval_address (count_exp); - count1 = count; - - if (target_has_stack == 0 || selected_frame == 0) - error ("No stack."); - - frame = find_relative_frame (selected_frame, &count1); - if (count1 != 0 && count_exp == 0) - error ("Initial frame selected; you cannot go up."); - select_frame (frame, selected_frame_level + count - count1); -} - -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); -} - -/* Select the frame down one or COUNT stack levels - from the previously selected frame, and print it briefly. */ - -/* ARGSUSED */ -static void -down_silently_command (count_exp, from_tty) - char *count_exp; - int from_tty; -{ - register FRAME frame; - int count = -1, count1; - if (count_exp) - count = - parse_and_eval_address (count_exp); - count1 = count; - - if (target_has_stack == 0 || selected_frame == 0) - error ("No stack."); - - frame = find_relative_frame (selected_frame, &count1); - if (count1 != 0 && count_exp == 0) - { - - /* We only do this if count_exp is not specified. That way "down" - means to really go down (and let me know if that is - impossible), but "down 9999" can be used to mean go all the way - down without getting an error. */ - - error ("Bottom (i.e., innermost) frame selected; you cannot go down."); - } - - select_frame (frame, selected_frame_level + count - count1); -} - - -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); -} - -static void -return_command (retval_exp, from_tty) - char *retval_exp; - int from_tty; -{ - struct symbol *thisfun; - FRAME_ADDR selected_frame_addr; - CORE_ADDR selected_frame_pc; - FRAME frame; - value_ptr return_value = NULL; - - if (selected_frame == NULL) - error ("No selected frame."); - thisfun = get_frame_function (selected_frame); - selected_frame_addr = FRAME_FP (selected_frame); - selected_frame_pc = (get_frame_info (selected_frame))->pc; - - /* Compute the return value (if any -- possibly getting errors here). */ - - if (retval_exp) - { - return_value = parse_and_eval (retval_exp); - - /* Make sure we have fully evaluated it, since - it might live in the stack frame we're about to pop. */ - if (VALUE_LAZY (return_value)) - value_fetch_lazy (return_value); - } - - /* If interactive, require confirmation. */ - - if (from_tty) - { - if (thisfun != 0) - { - if (!query ("Make %s return now? ", SYMBOL_SOURCE_NAME (thisfun))) - { - error ("Not confirmed."); - /* NOTREACHED */ - } - } - else - if (!query ("Make selected stack frame return now? ")) - error ("Not confirmed."); - } - - /* Do the real work. Pop until the specified frame is current. We - use this method because the selected_frame is not valid after - a POP_FRAME. The pc comparison makes this work even if the - selected frame shares its fp with another frame. */ - - while ( selected_frame_addr != FRAME_FP (frame = get_current_frame()) - || selected_frame_pc != (get_frame_info (frame))->pc ) - POP_FRAME; - - /* Then pop that frame. */ - - POP_FRAME; - - /* Compute the return value (if any) and store in the place - for return values. */ - - if (retval_exp) - set_return_value (return_value); - - /* If interactive, print the frame that is now current. */ - - if (from_tty) - frame_command ("0", 1); -} - -/* Gets the language of the current frame. */ -enum language -get_frame_language() -{ - register struct symtab *s; - FRAME fr; - enum language flang; /* The language of the current frame */ - - fr = get_frame_info(selected_frame); - if(fr) - { - s = find_pc_symtab(fr->pc); - if(s) - flang = s->language; - else - flang = language_unknown; - } - else - flang = language_unknown; - - return flang; -} - -void -_initialize_stack () -{ -#if 0 - backtrace_limit = 30; -#endif - - add_com ("return", class_stack, return_command, - "Make selected stack frame return to its caller.\n\ -Control remains in the debugger, but when you continue\n\ -execution will resume in the frame above the one now selected.\n\ -If an argument is given, it is an expression for the value to return."); - - add_com ("up", class_stack, up_command, - "Select and print stack frame that called this one.\n\ -An argument says how many frames up to go."); - add_com ("up-silently", class_support, up_silently_command, - "Same as the `up' command, but does not print anything.\n\ -This is useful in command scripts."); - - add_com ("down", class_stack, down_command, - "Select and print stack frame called by this one.\n\ -An argument says how many frames down to go."); - add_com_alias ("do", "down", class_stack, 1); - add_com_alias ("dow", "down", class_stack, 1); - add_com ("down-silently", class_support, down_silently_command, - "Same as the `down' command, but does not print anything.\n\ -This is useful in command scripts."); - - add_com ("frame", class_stack, frame_command, - "Select and print a stack frame.\n\ -With no argument, print the selected stack frame. (See also \"info frame\").\n\ -An argument specifies the frame to select.\n\ -It can be a stack frame number or the address of the frame.\n\ -With argument, nothing is printed if input is coming from\n\ -a command file or a user-defined command."); - - add_com_alias ("f", "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\ -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."); - add_com_alias ("bt", "backtrace", class_stack, 0); - add_com_alias ("where", "backtrace", class_alias, 0); - add_info ("stack", backtrace_command, - "Backtrace of the stack, or innermost COUNT frames."); - add_info_alias ("s", "stack", 1); - add_info ("frame", frame_info, - "All about selected stack frame, or frame at ADDR."); - add_info_alias ("f", "frame", 1); - add_info ("locals", locals_info, - "Local variables of current stack frame."); - add_info ("args", args_info, - "Argument variables of current stack frame."); - add_info ("catch", catch_info, - "Exceptions that can be caught in the current stack frame."); - -#if 0 - add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, - "Specify maximum number of frames for \"backtrace\" to print by default.", - &setlist); - add_info ("backtrace-limit", backtrace_limit_info, - "The maximum number of frames for \"backtrace\" to print by default."); -#endif -} diff --git a/gnu/usr.bin/gdb/gdb/symfile.c b/gnu/usr.bin/gdb/gdb/symfile.c deleted file mode 100644 index 7857041..0000000 --- a/gnu/usr.bin/gdb/gdb/symfile.c +++ /dev/null @@ -1,1684 +0,0 @@ -/* Generic symbol file reading for the GNU debugger, GDB. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by Cygnus Support, using pieces from other GDB modules. - -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 "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "gdbcore.h" -#include "frame.h" -#include "target.h" -#include "value.h" -#include "symfile.h" -#include "objfiles.h" -#include "gdbcmd.h" -#include "breakpoint.h" -#include "language.h" -#include "complaints.h" -#include "demangle.h" -#include "inferior.h" /* for write_pc */ - -#include -#include - -#include -#include -#include -#include -#include - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -/* Global variables owned by this file */ -int readnow_symbol_files; /* Read full symbols immediately */ - -struct complaint oldsyms_complaint = { - "Replacing old symbols for `%s'", 0, 0 -}; - -struct complaint empty_symtab_complaint = { - "Empty symbol table found for `%s'", 0, 0 -}; - -/* External variables and functions referenced. */ - -extern int info_verbose; - -/* Functions this file defines */ - -static void -set_initial_language PARAMS ((void)); - -static void -load_command PARAMS ((char *, int)); - -static void -add_symbol_file_command PARAMS ((char *, int)); - -static void -add_shared_symbol_files_command PARAMS ((char *, int)); - -static void -cashier_psymtab PARAMS ((struct partial_symtab *)); - -static int -compare_psymbols PARAMS ((const void *, const void *)); - -static int -compare_symbols PARAMS ((const void *, const void *)); - -static bfd * -symfile_bfd_open PARAMS ((char *)); - -static void -find_sym_fns PARAMS ((struct objfile *)); - -/* 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 - prepared to read. */ - -static struct sym_fns *symtab_fns = NULL; - -/* Structures with which to manage partial symbol allocation. */ - -struct psymbol_allocation_list global_psymbols = {0}, static_psymbols = {0}; - -/* Flag for whether user will be reloading symbols multiple times. - Defaults to ON for VxWorks, otherwise OFF. */ - -#ifdef SYMBOL_RELOADING_DEFAULT -int symbol_reloading = SYMBOL_RELOADING_DEFAULT; -#else -int symbol_reloading = 0; -#endif - - -/* Since this function is called from within qsort, in an ANSI environment - it must conform to the prototype for qsort, which specifies that the - comparison function takes two "void *" pointers. */ - -static int -compare_symbols (s1p, s2p) - const PTR s1p; - const PTR s2p; -{ - register struct symbol **s1, **s2; - - s1 = (struct symbol **) s1p; - s2 = (struct symbol **) s2p; - - return (STRCMP (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2))); -} - -/* - -LOCAL FUNCTION - - compare_psymbols -- compare two partial symbols by name - -DESCRIPTION - - Given pointer to two partial symbol table entries, compare - them by name and return -N, 0, or +N (ala strcmp). Typically - used by sorting routines like qsort(). - -NOTES - - Does direct compare of first two characters before punting - and passing to strcmp for longer compares. Note that the - original version had a bug whereby two null strings or two - identically named one character strings would return the - comparison of memory following the null byte. - - */ - -static int -compare_psymbols (s1p, s2p) - const PTR s1p; - const PTR s2p; -{ - register char *st1 = SYMBOL_NAME ((struct partial_symbol *) s1p); - register char *st2 = SYMBOL_NAME ((struct partial_symbol *) s2p); - - if ((st1[0] - st2[0]) || !st1[0]) - { - return (st1[0] - st2[0]); - } - else if ((st1[1] - st2[1]) || !st1[1]) - { - return (st1[1] - st2[1]); - } - else - { - return (STRCMP (st1 + 2, st2 + 2)); - } -} - -void -sort_pst_symbols (pst) - struct partial_symtab *pst; -{ - /* Sort the global list; don't sort the static list */ - - qsort (pst -> objfile -> global_psymbols.list + pst -> globals_offset, - pst -> n_global_syms, sizeof (struct partial_symbol), - compare_psymbols); -} - -/* Call sort_block_syms to sort alphabetically the symbols of one block. */ - -void -sort_block_syms (b) - register struct block *b; -{ - qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), - sizeof (struct symbol *), compare_symbols); -} - -/* Call sort_symtab_syms to sort alphabetically - the symbols of each block of one symtab. */ - -void -sort_symtab_syms (s) - register struct symtab *s; -{ - register struct blockvector *bv; - int nbl; - int i; - register struct block *b; - - if (s == 0) - return; - bv = BLOCKVECTOR (s); - nbl = BLOCKVECTOR_NBLOCKS (bv); - for (i = 0; i < nbl; i++) - { - b = BLOCKVECTOR_BLOCK (bv, i); - if (BLOCK_SHOULD_SORT (b)) - sort_block_syms (b); - } -} - -/* 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. */ - -char * -obsavestring (ptr, size, obstackp) - char *ptr; - int size; - struct obstack *obstackp; -{ - register char *p = (char *) obstack_alloc (obstackp, size + 1); - /* Open-coded memcpy--saves function call time. - These strings are usually short. */ - { - register char *p1 = ptr; - register char *p2 = p; - char *end = ptr + size; - while (p1 != end) - *p2++ = *p1++; - } - p[size] = 0; - return p; -} - -/* Concatenate strings S1, S2 and S3; return the new string. - Space is found in the symbol_obstack. */ - -char * -obconcat (obstackp, s1, s2, s3) - struct obstack *obstackp; - const char *s1, *s2, *s3; -{ - register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1; - register char *val = (char *) obstack_alloc (obstackp, len); - strcpy (val, s1); - strcat (val, s2); - strcat (val, s3); - return val; -} - -/* Get the symbol table that corresponds to a partial_symtab. - This is fast after the first time you do it. In fact, there - is an even faster macro PSYMTAB_TO_SYMTAB that does the fast - case inline. */ - -struct symtab * -psymtab_to_symtab (pst) - register struct partial_symtab *pst; -{ - /* If it's been looked up before, return it. */ - if (pst->symtab) - return pst->symtab; - - /* If it has not yet been read in, read it. */ - if (!pst->readin) - { - (*pst->read_symtab) (pst); - } - - return pst->symtab; -} - -/* Initialize entry point information for this objfile. */ - -void -init_entry_point_info (objfile) - struct objfile *objfile; -{ - /* Save startup file's range of PC addresses to help blockframe.c - decide where the bottom of the stack is. */ - - if (bfd_get_file_flags (objfile -> obfd) & EXEC_P) - { - /* Executable file -- record its entry point so we'll recognize - the startup file because it contains the entry point. */ - objfile -> ei.entry_point = bfd_get_start_address (objfile -> obfd); - } - else - { - /* Examination of non-executable.o files. Short-circuit this stuff. */ - objfile -> ei.entry_point = INVALID_ENTRY_POINT; - objfile -> ei.entry_file_lowpc = INVALID_ENTRY_LOWPC; - objfile -> ei.entry_file_highpc = INVALID_ENTRY_HIGHPC; - } -} - -/* Get current entry point address. */ - -CORE_ADDR -entry_point_address() -{ - return symfile_objfile ? symfile_objfile->ei.entry_point : 0; -} - -/* Remember the lowest-addressed loadable section we've seen. - This function is called via bfd_map_over_sections. */ - -#if 0 /* Not used yet */ -static void -find_lowest_section (abfd, sect, obj) - bfd *abfd; - asection *sect; - PTR obj; -{ - asection **lowest = (asection **)obj; - - if (0 == (bfd_get_section_flags (abfd, sect) & SEC_LOAD)) - return; - if (!*lowest) - *lowest = sect; /* First loadable section */ - else if (bfd_section_vma (abfd, *lowest) >= bfd_section_vma (abfd, sect)) - *lowest = sect; /* A lower loadable section */ -} -#endif - -/* Process a symbol file, as either the main file or as a dynamically - loaded file. - - NAME is the file name (which will be tilde-expanded and made - absolute herein) (but we don't free or modify NAME itself). - FROM_TTY says how verbose to be. MAINLINE specifies whether this - is the main symbol file, or whether it's an extra symbol file such - as dynamically loaded code. If !mainline, ADDR is the address - where the text segment was loaded. If VERBO, the caller has printed - a verbose message about the symbol reading (and complaints can be - more terse about it). */ - -void -syms_from_objfile (objfile, addr, mainline, verbo) - struct objfile *objfile; - CORE_ADDR addr; - int mainline; - int verbo; -{ - struct section_offsets *section_offsets; - asection *lowest_sect; - struct cleanup *old_chain; - - init_entry_point_info (objfile); - find_sym_fns (objfile); - - /* 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); - - 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); - - /* Since no error yet, throw away the old symbol table. */ - - if (symfile_objfile != NULL) - { - free_objfile (symfile_objfile); - symfile_objfile = NULL; - } - - /* Currently we keep symbols from the add-symbol-file command. - If the user wants to get rid of them, they should do "symbol-file" - without arguments first. Not sure this is the best behavior - (PR 2207). */ - - (*objfile -> sf -> sym_new_init) (objfile); - } - - /* Convert addr into an offset rather than an absolute address. - We find the lowest address of a loaded segment in the objfile, - and assume that is where that got loaded. Due to historical - precedent, we warn if that doesn't happen to be the ".text" - segment. */ - - if (mainline) - { - addr = 0; /* No offset from objfile addresses. */ - } - else - { - lowest_sect = bfd_get_section_by_name (objfile->obfd, ".text"); -#if 0 - lowest_sect = 0; - bfd_map_over_sections (objfile->obfd, find_lowest_section, - (PTR) &lowest_sect); -#endif - - if (lowest_sect == 0) - warning ("no loadable sections found in added symbol-file %s", - objfile->name); - else if (0 == bfd_get_section_name (objfile->obfd, lowest_sect) - || !STREQ (".text", - bfd_get_section_name (objfile->obfd, lowest_sect))) - /* FIXME-32x64--assumes bfd_vma fits in long. */ - warning ("Lowest section in %s is %s at 0x%lx", - objfile->name, - bfd_section_name (objfile->obfd, lowest_sect), - (unsigned long) bfd_section_vma (objfile->obfd, lowest_sect)); - - if (lowest_sect) - addr -= bfd_section_vma (objfile->obfd, lowest_sect); - } - - /* Initialize symbol reading routines for this objfile, allow complaints to - appear for this new file, and record how verbose to be, then do the - initial symbol reading for this file. */ - - (*objfile -> sf -> sym_init) (objfile); - clear_complaints (1, verbo); - - section_offsets = (*objfile -> sf -> sym_offsets) (objfile, addr); - objfile->section_offsets = section_offsets; - -#ifndef IBM6000_TARGET - /* This is a SVR4/SunOS specific hack, I think. In any event, it - screws RS/6000. sym_offsets should be doing this sort of thing, - because it knows the mapping between bfd sections and - section_offsets. */ - /* This is a hack. As far as I can tell, section offsets are not - target dependent. They are all set to addr with a couple of - exceptions. The exceptions are sysvr4 shared libraries, whose - offsets are kept in solib structures anyway and rs6000 xcoff - which handles shared libraries in a completely unique way. - - Section offsets are built similarly, except that they are built - by adding addr in all cases because there is no clear mapping - from section_offsets into actual sections. Note that solib.c - has a different algorythm for finding section offsets. - - These should probably all be collapsed into some target - independent form of shared library support. FIXME. */ - - if (addr) - { - struct obj_section *s; - - for (s = objfile->sections; s < objfile->sections_end; ++s) - { - s->addr -= s->offset; - s->addr += addr; - s->endaddr -= s->offset; - s->endaddr += addr; - s->offset += addr; - } - } -#endif /* not IBM6000_TARGET */ - - (*objfile -> sf -> sym_read) (objfile, section_offsets, mainline); - - if (!have_partial_symbols () && !have_full_symbols ()) - { - wrap_here (""); - printf_filtered ("(no debugging symbols found)..."); - wrap_here (""); - } - - /* Don't allow char * to have a typename (else would get caddr_t). - Ditto void *. FIXME: Check whether this is now done by all the - symbol readers themselves (many of them now do), and if so remove - it from here. */ - - TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; - TYPE_NAME (lookup_pointer_type (builtin_type_void)) = 0; - - /* Mark the objfile has having had initial symbol read attempted. Note - that this does not mean we found any symbols... */ - - objfile -> flags |= OBJF_SYMS; - - /* Discard cleanups as symbol reading was successful. */ - - discard_cleanups (old_chain); -} - -/* Perform required actions after either reading in the initial - symbols for a new objfile, or mapping in the symbols from a reusable - objfile. */ - -void -new_symfile_objfile (objfile, mainline, verbo) - struct objfile *objfile; - int mainline; - int verbo; -{ - - /* If this is the main symbol file we have to clean up all users of the - old main symbol file. Otherwise it is sufficient to fixup all the - breakpoints that may have been redefined by this symbol file. */ - if (mainline) - { - /* OK, make it the "real" symbol file. */ - symfile_objfile = objfile; - - clear_symtab_users (); - } - else - { - breakpoint_re_set (); - } - - /* We're done reading the symbol file; finish off complaints. */ - clear_complaints (0, verbo); -} - -/* Process a symbol file, as either the main file or as a dynamically - loaded file. - - NAME is the file name (which will be tilde-expanded and made - absolute herein) (but we don't free or modify NAME itself). - FROM_TTY says how verbose to be. MAINLINE specifies whether this - is the main symbol file, or whether it's an extra symbol file such - as dynamically loaded code. If !mainline, ADDR is the address - where the text segment was loaded. - - 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) - char *name; - int from_tty; - CORE_ADDR addr; - int mainline; - int mapped; - int readnow; -{ - struct objfile *objfile; - struct partial_symtab *psymtab; - bfd *abfd; - - /* Open a bfd for the file, and give user a chance to burp if we'd be - interactively wiping out any existing symbols. */ - - abfd = symfile_bfd_open (name); - - if ((have_full_symbols () || have_partial_symbols ()) - && mainline - && from_tty - && !query ("Load new symbol table from \"%s\"? ", name)) - error ("Not confirmed."); - - objfile = allocate_objfile (abfd, mapped); - - /* If the objfile uses a mapped symbol file, and we have a psymtab for - it, then skip reading any symbols at this time. */ - - if ((objfile -> flags & OBJF_MAPPED) && (objfile -> flags & OBJF_SYMS)) - { - /* We mapped in an existing symbol table file that already has had - initial symbol reading performed, so we can skip that part. Notify - the user that instead of reading the symbols, they have been mapped. - */ - if (from_tty || info_verbose) - { - printf_filtered ("Mapped symbols for %s...", name); - wrap_here (""); - gdb_flush (gdb_stdout); - } - init_entry_point_info (objfile); - find_sym_fns (objfile); - } - else - { - /* We either created a new mapped symbol table, mapped an existing - symbol table file which has not had initial symbol reading - 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); - } - 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 - the gdb startup command line or on a per symbol file basis. Expand - all partial symbol tables for this objfile if so. */ - - if (readnow || readnow_symbol_files) - { - if (from_tty || info_verbose) - { - printf_filtered ("expanding to full symbols..."); - wrap_here (""); - gdb_flush (gdb_stdout); - } - - for (psymtab = objfile -> psymtabs; - psymtab != NULL; - psymtab = psymtab -> next) - { - psymtab_to_symtab (psymtab); - } - } - - if (from_tty || info_verbose) - { - printf_filtered ("done.\n"); - gdb_flush (gdb_stdout); - } - - new_symfile_objfile (objfile, mainline, from_tty); - - /* Getting new symbols may change our opinion about what is - frameless. */ - - reinit_frame_cache (); - - return (objfile); -} - -/* This is the symbol-file command. Read the file, analyze its - symbols, and add a struct symtab to a symtab list. The syntax of - the command is rather bizarre--(1) buildargv implements various - quoting conventions which are undocumented and have little or - nothing in common with the way things are quoted (or not quoted) - elsewhere in GDB, (2) options are used, which are not generally - used in GDB (perhaps "set mapped on", "set readnow on" would be - better), (3) the order of options matters, which is contrary to GNU - conventions (because it is confusing and inconvenient). */ - -void -symbol_file_command (args, from_tty) - char *args; - int from_tty; -{ - char **argv; - char *name = NULL; - CORE_ADDR text_relocation = 0; /* text_relocation */ - struct cleanup *cleanups; - int mapped = 0; - int readnow = 0; - - dont_repeat (); - - if (args == NULL) - { - if ((have_full_symbols () || have_partial_symbols ()) - && from_tty - && !query ("Discard symbol table from `%s'? ", - symfile_objfile -> name)) - error ("Not confirmed."); - free_all_objfiles (); - symfile_objfile = NULL; - if (from_tty) - { - printf_unfiltered ("No symbol file now.\n"); - } - } - else - { - if ((argv = buildargv (args)) == NULL) - { - nomem (0); - } - cleanups = make_cleanup (freeargv, (char *) argv); - while (*argv != NULL) - { - if (STREQ (*argv, "-mapped")) - { - mapped = 1; - } - else if (STREQ (*argv, "-readnow")) - { - readnow = 1; - } - else if (**argv == '-') - { - error ("unknown option `%s'", *argv); - } - else - { - char *p; - - name = *argv; - - /* this is for rombug remote only, to get the text relocation by - using link command */ - p = strrchr(name, '/'); - if (p != NULL) p++; - else p = name; - - target_link(p, &text_relocation); - - 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); - else - symbol_file_add (name, from_tty, (CORE_ADDR)text_relocation, - 0, mapped, readnow); - set_initial_language (); - } - argv++; - } - - if (name == NULL) - { - error ("no symbol file name was specified"); - } - do_cleanups (cleanups); - } -} - -/* Set the initial language. - - A better solution would be to record the language in the psymtab when reading - partial symbols, and then use it (if known) to set the language. This would - be a win for formats that encode the language in an easily discoverable place, - such as DWARF. For stabs, we can jump through hoops looking for specially - named symbols or try to intuit the language from the specific type of stabs - we find, but we can't do that until later when we read in full symbols. - FIXME. */ - -static void -set_initial_language () -{ - struct partial_symtab *pst; - enum language lang = language_unknown; - - pst = find_main_psymtab (); - if (pst != NULL) - { - if (pst -> filename != NULL) - { - lang = deduce_language_from_filename (pst -> filename); - } - if (lang == language_unknown) - { - /* Make C the default language */ - lang = language_c; - } - set_language (lang); - expected_language = current_language; /* Don't warn the user */ - } -} - -/* Open file specified by NAME and hand it off to BFD for preliminary - analysis. Result is a newly initialized bfd *, which includes a newly - malloc'd` copy of NAME (tilde-expanded and made absolute). - In case of trouble, error() is called. */ - -static bfd * -symfile_bfd_open (name) - char *name; -{ - bfd *sym_bfd; - 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 (desc < 0) - { - make_cleanup (free, name); - perror_with_name (name); - } - free (name); /* Free 1st new malloc'd copy */ - name = absolute_name; /* Keep 2nd malloc'd copy in bfd */ - /* It'll be freed in free_objfile(). */ - - sym_bfd = bfd_fdopenr (name, gnutarget, desc); - if (!sym_bfd) - { - close (desc); - make_cleanup (free, name); - error ("\"%s\": can't open to read symbols: %s.", name, - bfd_errmsg (bfd_get_error ())); - } - sym_bfd->cacheable = true; - - if (!bfd_check_format (sym_bfd, bfd_object)) - { - bfd_close (sym_bfd); /* This also closes desc */ - make_cleanup (free, name); - error ("\"%s\": can't read symbols: %s.", name, - bfd_errmsg (bfd_get_error ())); - } - - return (sym_bfd); -} - -/* Link a new symtab_fns into the global symtab_fns list. Called on gdb - startup by the _initialize routine in each object file format reader, - to register information about each format the the reader is prepared - to handle. */ - -void -add_symtab_fns (sf) - struct sym_fns *sf; -{ - sf->next = symtab_fns; - symtab_fns = sf; -} - - -/* Initialize to read symbols from the symbol file sym_bfd. It either - returns or calls error(). The result is an initialized struct sym_fns - in the objfile structure, that contains cached information about the - symbol file. */ - -static void -find_sym_fns (objfile) - struct objfile *objfile; -{ - struct sym_fns *sf; - enum bfd_flavour our_flavour = bfd_get_flavour (objfile -> obfd); - char *our_target = bfd_get_target (objfile -> obfd); - - /* Special kludge for RS/6000. See xcoffread.c. */ - if (STREQ (our_target, "aixcoff-rs6000")) - our_flavour = (enum bfd_flavour)-1; - - /* Special kludge for apollo. See dstread.c. */ - if (STREQN (our_target, "apollo", 6)) - our_flavour = (enum bfd_flavour)-2; - - for (sf = symtab_fns; sf != NULL; sf = sf -> next) - { - if (our_flavour == sf -> sym_flavour) - { - objfile -> sf = sf; - return; - } - } - error ("I'm sorry, Dave, I can't do that. Symbol format `%s' unknown.", - bfd_get_target (objfile -> obfd)); -} - -/* This function runs the load command of our current target. */ - -static void -load_command (arg, from_tty) - char *arg; - int from_tty; -{ - target_load (arg, from_tty); -} - -/* This version of "load" should be usable for any target. Currently - it is just used for remote targets, not inftarg.c or core files, - on the theory that only in that case is it useful. - - Avoiding xmodem and the like seems like a win (a) because we don't have - 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. */ -void -generic_load (filename, from_tty) - char *filename; - int from_tty; -{ - struct cleanup *old_cleanups; - asection *s; - bfd *loadfile_bfd; - - if (filename == NULL) - filename = get_exec_file (1); - - loadfile_bfd = bfd_openr (filename, gnutarget); - if (loadfile_bfd == NULL) - { - perror_with_name (filename); - return; - } - old_cleanups = make_cleanup (bfd_close, loadfile_bfd); - - if (!bfd_check_format (loadfile_bfd, bfd_object)) - { - error ("\"%s\" is not an object file: %s", filename, - bfd_errmsg (bfd_get_error ())); - } - - 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; - - buffer = xmalloc (size); - old_chain = make_cleanup (free, buffer); - - vma = bfd_get_section_vma (loadfile_bfd, s); - - /* 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); - } - } - } - - /* We were doing this in remote-mips.c, I suspect it is right - for other targets too. */ - write_pc (loadfile_bfd->start_address); - - /* 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 - commented out), making the call confuses GDB if more than one file is - loaded in. remote-nindy.c had no call to symbol_file_add, but remote-vx.c - does. */ - - do_cleanups (old_cleanups); -} - -/* This function allows the addition of incrementally linked object files. - It does not modify any state in the target, only in the debugger. */ - -/* ARGSUSED */ -static void -add_symbol_file_command (args, from_tty) - char *args; - int from_tty; -{ - char *name = NULL; - CORE_ADDR text_addr; - char *arg; - int readnow = 0; - int mapped = 0; - - dont_repeat (); - - if (args == NULL) - { - error ("add-symbol-file takes a file name and an address"); - } - - /* Make a copy of the string that we can safely write into. */ - - args = strdup (args); - make_cleanup (free, args); - - /* Pick off any -option args and the file name. */ - - while ((*args != '\000') && (name == NULL)) - { - while (isspace (*args)) {args++;} - arg = args; - while ((*args != '\000') && !isspace (*args)) {args++;} - if (*args != '\000') - { - *args++ = '\000'; - } - if (*arg != '-') - { - name = arg; - } - else if (STREQ (arg, "-mapped")) - { - mapped = 1; - } - else if (STREQ (arg, "-readnow")) - { - readnow = 1; - } - else - { - error ("unknown option `%s'", arg); - } - } - - /* After picking off any options and the file name, args should be - left pointing at the remainder of the command line, which should - be the address expression to evaluate. */ - - if (name == NULL) - { - error ("add-symbol-file takes a file name"); - } - name = tilde_expand (name); - make_cleanup (free, name); - - if (*args != '\000') - { - text_addr = parse_and_eval_address (args); - } - else - { - target_link(name, &text_addr); - if (text_addr == (CORE_ADDR)-1) - error("Don't know how to get text start location for this file"); - } - - /* 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))) - error ("Not confirmed."); - - symbol_file_add (name, 0, text_addr, 0, mapped, readnow); -} - -static void -add_shared_symbol_files_command (args, from_tty) - char *args; - int from_tty; -{ -#ifdef ADD_SHARED_SYMBOL_FILES - ADD_SHARED_SYMBOL_FILES (args, from_tty); -#else - error ("This command is not available in this configuration of GDB."); -#endif -} - -/* Re-read symbols if a symbol-file has changed. */ -void -reread_symbols () -{ - struct objfile *objfile; - long new_modtime; - int reread_one = 0; - struct stat new_statbuf; - int res; - - /* With the addition of shared libraries, this should be modified, - the load time should be saved in the partial symbol tables, since - different tables may come from different source files. FIXME. - This routine should then walk down each partial symbol table - and see if the symbol table that it originates from has been changed */ - - for (objfile = object_files; objfile; objfile = objfile->next) { - if (objfile->obfd) { -#ifdef IBM6000_TARGET - /* If this object is from a shared library, then you should - stat on the library name, not member name. */ - - if (objfile->obfd->my_archive) - res = stat (objfile->obfd->my_archive->filename, &new_statbuf); - else -#endif - res = stat (objfile->name, &new_statbuf); - if (res != 0) { - /* FIXME, should use print_sys_errmsg but it's not filtered. */ - printf_filtered ("`%s' has disappeared; keeping its symbols.\n", - objfile->name); - continue; - } - new_modtime = new_statbuf.st_mtime; - if (new_modtime != objfile->mtime) - { - struct cleanup *old_cleanups; - struct section_offsets *offsets; - int num_offsets; - int section_offsets_size; - - printf_filtered ("`%s' has changed; re-reading symbols.\n", - objfile->name); - - /* There are various functions like symbol_file_add, - symfile_bfd_open, syms_from_objfile, etc., which might - appear to do what we want. But they have various other - effects which we *don't* want. So we just do stuff - ourselves. We don't worry about mapped files (for one thing, - any mapped file will be out of date). */ - - /* 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); - /* We need to do this whenever any symbols go away. */ - make_cleanup (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 - BFD without closing the descriptor. */ - if (!bfd_close (objfile->obfd)) - error ("Can't close BFD for %s.", objfile->name); - objfile->obfd = bfd_openr (objfile->name, gnutarget); - if (objfile->obfd == NULL) - error ("Can't open %s to read symbols.", objfile->name); - /* bfd_openr sets cacheable to true, which is what we want. */ - if (!bfd_check_format (objfile->obfd, bfd_object)) - error ("Can't read symbols from %s: %s.", objfile->name, - bfd_errmsg (bfd_get_error ())); - - /* Save the offsets, we will nuke them with the rest of the - psymbol_obstack. */ - num_offsets = objfile->num_sections; - section_offsets_size = - sizeof (struct section_offsets) - + sizeof (objfile->section_offsets->offsets) * num_offsets; - offsets = (struct section_offsets *) alloca (section_offsets_size); - memcpy (offsets, objfile->section_offsets, section_offsets_size); - - /* Nuke all the state that we will re-read. Much of the following - code which sets things to NULL really is necessary to tell - other parts of GDB that there is nothing currently there. */ - - /* FIXME: Do we have to free a whole linked list, or is this - enough? */ - if (objfile->global_psymbols.list) - mfree (objfile->md, objfile->global_psymbols.list); - objfile->global_psymbols.list = NULL; - objfile->global_psymbols.next = NULL; - objfile->global_psymbols.size = 0; - if (objfile->static_psymbols.list) - mfree (objfile->md, objfile->static_psymbols.list); - objfile->static_psymbols.list = NULL; - objfile->static_psymbols.next = NULL; - objfile->static_psymbols.size = 0; - - /* Free the obstacks for non-reusable objfiles */ - obstack_free (&objfile -> psymbol_obstack, 0); - obstack_free (&objfile -> symbol_obstack, 0); - obstack_free (&objfile -> type_obstack, 0); - objfile->sections = NULL; - objfile->symtabs = NULL; - objfile->psymtabs = NULL; - objfile->free_psymtabs = NULL; - objfile->msymbols = NULL; - objfile->minimal_symbol_count= 0; - objfile->fundamental_types = NULL; - if (objfile -> sf != NULL) - { - (*objfile -> sf -> sym_finish) (objfile); - } - - /* We never make this a mapped file. */ - objfile -> md = NULL; - /* obstack_specify_allocation also initializes the obstack so - it is empty. */ - obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0, - xmalloc, free); - obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0, - xmalloc, free); - obstack_specify_allocation (&objfile -> type_obstack, 0, 0, - xmalloc, free); - if (build_objfile_section_table (objfile)) - { - error ("Can't find the file sections in `%s': %s", - objfile -> name, bfd_errmsg (bfd_get_error ())); - } - - /* We use the same section offsets as from last time. I'm not - sure whether that is always correct for shared libraries. */ - objfile->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile -> psymbol_obstack, section_offsets_size); - memcpy (objfile->section_offsets, offsets, section_offsets_size); - objfile->num_sections = num_offsets; - - /* What the hell is sym_new_init for, anyway? The concept of - 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_init) (objfile); - clear_complaints (1, 1); - /* The "mainline" parameter is a hideous hack; I think leaving it - zero is OK since dbxread.c also does what it needs to do if - objfile->global_psymbols.size is 0. */ - (*objfile->sf->sym_read) (objfile, objfile->section_offsets, 0); - if (!have_partial_symbols () && !have_full_symbols ()) - { - wrap_here (""); - printf_filtered ("(no debugging symbols found)\n"); - wrap_here (""); - } - objfile -> flags |= OBJF_SYMS; - - /* We're done reading the symbol file; finish off complaints. */ - clear_complaints (0, 1); - - /* Getting new symbols may change our opinion about what is - frameless. */ - - reinit_frame_cache (); - - /* Discard cleanups as symbol reading was successful. */ - discard_cleanups (old_cleanups); - - /* If the mtime has changed between the time we set new_modtime - and now, we *want* this to be out of date, so don't call stat - again now. */ - objfile->mtime = new_modtime; - reread_one = 1; - } - } - } - - if (reread_one) - clear_symtab_users (); -} - - -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,".mod")) - return language_m2; - else if (STREQ(c,".c")) - return language_c; - else if (STREQ(c,".s")) - return language_asm; - else if (STREQ (c,".cc") || STREQ (c,".C") || STREQ (c, ".cxx") - || STREQ (c, ".cpp")) - return language_cplus; - else if (STREQ (c,".ch") || STREQ (c,".c186") || STREQ (c,".c286")) - return language_chill; - - return language_unknown; /* default */ -} - -/* allocate_symtab: - - Allocate and partly initialize a new symbol table. Return a pointer - to it. error() if no space. - - Caller must set these fields: - LINETABLE(symtab) - symtab->blockvector - symtab->dirname - symtab->free_code - symtab->free_ptr - initialize any EXTRA_SYMTAB_INFO - possibly free_named_symtabs (symtab->filename); - */ - -struct symtab * -allocate_symtab (filename, objfile) - char *filename; - struct objfile *objfile; -{ - register struct symtab *symtab; - - symtab = (struct symtab *) - obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symtab)); - memset (symtab, 0, sizeof (*symtab)); - symtab -> filename = obsavestring (filename, strlen (filename), - &objfile -> symbol_obstack); - symtab -> fullname = NULL; - symtab -> language = deduce_language_from_filename (filename); - - /* Hook it to the objfile it comes from */ - - symtab -> objfile = objfile; - symtab -> next = objfile -> symtabs; - objfile -> symtabs = symtab; - -#ifdef INIT_EXTRA_SYMTAB_INFO - INIT_EXTRA_SYMTAB_INFO (symtab); -#endif - - return (symtab); -} - -struct partial_symtab * -allocate_psymtab (filename, objfile) - char *filename; - struct objfile *objfile; -{ - struct partial_symtab *psymtab; - - if (objfile -> free_psymtabs) - { - psymtab = objfile -> free_psymtabs; - objfile -> free_psymtabs = psymtab -> next; - } - else - psymtab = (struct partial_symtab *) - obstack_alloc (&objfile -> psymbol_obstack, - sizeof (struct partial_symtab)); - - memset (psymtab, 0, sizeof (struct partial_symtab)); - psymtab -> filename = obsavestring (filename, strlen (filename), - &objfile -> psymbol_obstack); - psymtab -> symtab = NULL; - - /* Hook it to the objfile it comes from */ - - psymtab -> objfile = objfile; - psymtab -> next = objfile -> psymtabs; - objfile -> psymtabs = psymtab; - - return (psymtab); -} - - -/* Reset all data structures in gdb which may contain references to symbol - table date. */ - -void -clear_symtab_users () -{ - /* Someday, we should do better than this, by only blowing away - the things that really need to be blown. */ - clear_value_history (); - clear_displays (); - clear_internalvars (); - breakpoint_re_set (); - set_default_breakpoint (0, 0, 0, 0); - current_source_symtab = 0; - current_source_line = 0; - clear_pc_function_cache (); -} - -/* clear_symtab_users_once: - - This function is run after symbol reading, or from a cleanup. - If an old symbol table was obsoleted, the old symbol table - has been blown away, but the other GDB data structures that may - reference it have not yet been cleared or re-directed. (The old - symtab was zapped, and the cleanup queued, in free_named_symtab() - below.) - - This function can be queued N times as a cleanup, or called - directly; it will do all the work the first time, and then will be a - no-op until the next time it is queued. This works by bumping a - counter at queueing time. Much later when the cleanup is run, or at - the end of symbol processing (in case the cleanup is discarded), if - the queued count is greater than the "done-count", we do the work - and set the done-count to the queued count. If the queued count is - less than or equal to the done-count, we just ignore the call. This - is needed because reading a single .o file will often replace many - symtabs (one per .h file, for example), and we don't want to reset - the breakpoints N times in the user's face. - - The reason we both queue a cleanup, and call it directly after symbol - reading, is because the cleanup protects us in case of errors, but is - discarded if symbol reading is successful. */ - -#if 0 -/* FIXME: As free_named_symtabs is currently a big noop this function - is no longer needed. */ -static void -clear_symtab_users_once PARAMS ((void)); - -static int clear_symtab_users_queued; -static int clear_symtab_users_done; - -static void -clear_symtab_users_once () -{ - /* Enforce once-per-`do_cleanups'-semantics */ - if (clear_symtab_users_queued <= clear_symtab_users_done) - return; - clear_symtab_users_done = clear_symtab_users_queued; - - clear_symtab_users (); -} -#endif - -/* Delete the specified psymtab, and any others that reference it. */ - -static void -cashier_psymtab (pst) - struct partial_symtab *pst; -{ - struct partial_symtab *ps, *pprev = NULL; - int i; - - /* Find its previous psymtab in the chain */ - for (ps = pst->objfile->psymtabs; ps; ps = ps->next) { - if (ps == pst) - break; - pprev = ps; - } - - if (ps) { - /* Unhook it from the chain. */ - if (ps == pst->objfile->psymtabs) - pst->objfile->psymtabs = ps->next; - else - pprev->next = ps->next; - - /* FIXME, we can't conveniently deallocate the entries in the - partial_symbol lists (global_psymbols/static_psymbols) that - this psymtab points to. These just take up space until all - the psymtabs are reclaimed. Ditto the dependencies list and - filename, which are all in the psymbol_obstack. */ - - /* We need to cashier any psymtab that has this one as a dependency... */ -again: - for (ps = pst->objfile->psymtabs; ps; ps = ps->next) { - for (i = 0; i < ps->number_of_dependencies; i++) { - if (ps->dependencies[i] == pst) { - cashier_psymtab (ps); - goto again; /* Must restart, chain has been munged. */ - } - } - } - } -} - -/* If a symtab or psymtab for filename NAME is found, free it along - with any dependent breakpoints, displays, etc. - Used when loading new versions of object modules with the "add-file" - command. This is only called on the top-level symtab or psymtab's name; - it is not called for subsidiary files such as .h files. - - Return value is 1 if we blew away the environment, 0 if not. - FIXME. The return valu appears to never be used. - - FIXME. I think this is not the best way to do this. We should - work on being gentler to the environment while still cleaning up - all stray pointers into the freed symtab. */ - -int -free_named_symtabs (name) - char *name; -{ -#if 0 - /* FIXME: With the new method of each objfile having it's own - psymtab list, this function needs serious rethinking. In particular, - why was it ever necessary to toss psymtabs with specific compilation - unit filenames, as opposed to all psymtabs from a particular symbol - file? -- fnf - Well, the answer is that some systems permit reloading of particular - compilation units. We want to blow away any old info about these - compilation units, regardless of which objfiles they arrived in. --gnu. */ - - register struct symtab *s; - register struct symtab *prev; - register struct partial_symtab *ps; - struct blockvector *bv; - int blewit = 0; - - /* We only wack things if the symbol-reload switch is set. */ - if (!symbol_reloading) - return 0; - - /* Some symbol formats have trouble providing file names... */ - if (name == 0 || *name == '\0') - return 0; - - /* Look for a psymtab with the specified name. */ - -again2: - for (ps = partial_symtab_list; ps; ps = ps->next) { - if (STREQ (name, ps->filename)) { - cashier_psymtab (ps); /* Blow it away...and its little dog, too. */ - goto again2; /* Must restart, chain has been munged */ - } - } - - /* Look for a symtab with the specified name. */ - - for (s = symtab_list; s; s = s->next) - { - if (STREQ (name, s->filename)) - break; - prev = s; - } - - if (s) - { - if (s == symtab_list) - symtab_list = s->next; - else - prev->next = s->next; - - /* For now, queue a delete for all breakpoints, displays, etc., whether - or not they depend on the symtab being freed. This should be - changed so that only those data structures affected are deleted. */ - - /* But don't delete anything if the symtab is empty. - This test is necessary due to a bug in "dbxread.c" that - causes empty symtabs to be created for N_SO symbols that - contain the pathname of the object file. (This problem - has been fixed in GDB 3.9x). */ - - bv = BLOCKVECTOR (s); - if (BLOCKVECTOR_NBLOCKS (bv) > 2 - || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) - || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK))) - { - complain (&oldsyms_complaint, name); - - clear_symtab_users_queued++; - make_cleanup (clear_symtab_users_once, 0); - blewit = 1; - } else { - complain (&empty_symtab_complaint, name); - } - - free_symtab (s); - } - else - { - /* It is still possible that some breakpoints will be affected - even though no symtab was found, since the file might have - been compiled without debugging, and hence not be associated - with a symtab. In order to handle this correctly, we would need - to keep a list of text address ranges for undebuggable files. - For now, we do nothing, since this is a fairly obscure case. */ - ; - } - - /* FIXME, what about the minimal symbol table? */ - return blewit; -#else - return (0); -#endif -} - -/* 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). */ - - -struct partial_symtab * -start_psymtab_common (objfile, section_offsets, - filename, textlow, global_syms, static_syms) - struct objfile *objfile; - struct section_offsets *section_offsets; - char *filename; - CORE_ADDR textlow; - struct partial_symbol *global_syms; - struct partial_symbol *static_syms; -{ - struct partial_symtab *psymtab; - - psymtab = allocate_psymtab (filename, objfile); - psymtab -> section_offsets = section_offsets; - psymtab -> textlow = textlow; - psymtab -> texthigh = psymtab -> textlow; /* default */ - psymtab -> globals_offset = global_syms - objfile -> global_psymbols.list; - psymtab -> statics_offset = static_syms - objfile -> static_psymbols.list; - return (psymtab); -} - -/* Debugging versions of functions that are usually inline macros - (see symfile.h). */ - -#if !INLINE_ADD_PSYMBOL - -/* Add a symbol with a long value to a psymtab. - Since one arg is a struct, we pass in a ptr and deref it (sigh). */ - -void -add_psymbol_to_list (name, namelength, namespace, class, list, val, language, - objfile) - char *name; - int namelength; - enum namespace namespace; - enum address_class class; - struct psymbol_allocation_list *list; - long val; - enum language language; - struct objfile *objfile; -{ - register struct partial_symbol *psym; - register char *demangled_name; - - if (list->next >= list->list + list->size) - { - extend_psymbol_list (list,objfile); - } - psym = list->next++; - - SYMBOL_NAME (psym) = - (char *) obstack_alloc (&objfile->psymbol_obstack, namelength + 1); - memcpy (SYMBOL_NAME (psym), name, namelength); - SYMBOL_NAME (psym)[namelength] = '\0'; - SYMBOL_VALUE (psym) = val; - SYMBOL_LANGUAGE (psym) = language; - PSYMBOL_NAMESPACE (psym) = namespace; - PSYMBOL_CLASS (psym) = class; - SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack); -} - -/* Add a symbol with a CORE_ADDR value to a psymtab. */ - -void -add_psymbol_addr_to_list (name, namelength, namespace, class, list, val, - language, objfile) - char *name; - int namelength; - enum namespace namespace; - enum address_class class; - struct psymbol_allocation_list *list; - CORE_ADDR val; - enum language language; - struct objfile *objfile; -{ - register struct partial_symbol *psym; - register char *demangled_name; - - if (list->next >= list->list + list->size) - { - extend_psymbol_list (list,objfile); - } - psym = list->next++; - - SYMBOL_NAME (psym) = - (char *) obstack_alloc (&objfile->psymbol_obstack, namelength + 1); - memcpy (SYMBOL_NAME (psym), name, namelength); - SYMBOL_NAME (psym)[namelength] = '\0'; - SYMBOL_VALUE_ADDRESS (psym) = val; - SYMBOL_LANGUAGE (psym) = language; - PSYMBOL_NAMESPACE (psym) = namespace; - PSYMBOL_CLASS (psym) = class; - SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack); -} - -#endif /* !INLINE_ADD_PSYMBOL */ - - -void -_initialize_symfile () -{ - struct cmd_list_element *c; - - c = add_cmd ("symbol-file", class_files, symbol_file_command, - "Load symbol table from executable file FILE.\n\ -The `file' command can also load symbol tables, as well as setting the file\n\ -to execute.", &cmdlist); - c->completer = filename_completer; - - c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command, - "Usage: add-symbol-file FILE ADDR\n\ -Load the symbols from FILE, assuming FILE has been dynamically loaded.\n\ -ADDR is the starting address of the file's text.", - &cmdlist); - c->completer = filename_completer; - - c = add_cmd ("add-shared-symbol-files", class_files, - add_shared_symbol_files_command, - "Load the symbols from shared objects in the dynamic linker's link map.", - &cmdlist); - c = add_alias_cmd ("assf", "add-shared-symbol-files", class_files, 1, - &cmdlist); - - c = add_cmd ("load", class_files, load_command, - "Dynamically load FILE into the running program, and record its symbols\n\ -for access from GDB.", &cmdlist); - c->completer = filename_completer; - - add_show_from_set - (add_set_cmd ("symbol-reloading", class_support, var_boolean, - (char *)&symbol_reloading, - "Set dynamic symbol table reloading multiple times in one run.", - &setlist), - &showlist); - -} diff --git a/gnu/usr.bin/gdb/gdb/symfile.h b/gnu/usr.bin/gdb/gdb/symfile.h deleted file mode 100644 index 17303bb..0000000 --- a/gnu/usr.bin/gdb/gdb/symfile.h +++ /dev/null @@ -1,250 +0,0 @@ -/* Definitions for reading symbol files into GDB. - Copyright (C) 1990, 1991, 1992 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 (SYMFILE_H) -#define SYMFILE_H - -/* This file requires that you first include "bfd.h". */ - -struct psymbol_allocation_list { - struct partial_symbol *list; - struct partial_symbol *next; - int size; -}; - -/* Structure to keep track of symbol reading functions for various - object file types. */ - -struct sym_fns { - - /* BFD flavour that we handle, or (as a special kludge, see xcoffread.c, - (enum bfd_flavour)-1 for xcoff). */ - - enum bfd_flavour sym_flavour; - - /* Initializes anything that is global to the entire symbol table. It is - called during symbol_file_add, when we begin debugging an entirely new - program. */ - - void (*sym_new_init) PARAMS ((struct objfile *)); - - /* Reads any initial information from a symbol file, and initializes the - struct sym_fns SF in preparation for sym_read(). It is called every - time we read a symbol file for any reason. */ - - void (*sym_init) PARAMS ((struct objfile *)); - - /* sym_read (objfile, addr, mainline) - Reads a symbol file into a psymtab (or possibly a symtab). - OBJFILE is the objfile struct for the file we are reading. - SECTION_OFFSETS - are the offset between the file's specified section addresses and - their true addresses in memory. - 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. */ - - void (*sym_read) PARAMS ((struct objfile *, struct section_offsets *, int)); - - /* Called when we are finished with an objfile. Should do all cleanup - that is specific to the object file format for the particular objfile. */ - - void (*sym_finish) PARAMS ((struct objfile *)); - - /* This function produces a file-dependent section_offsets structure, - allocated in the objfile's storage, and based on the parameter. - The parameter is currently a CORE_ADDR (FIXME!) for backward compatibility - with the higher levels of GDB. It should probably be changed to - a string, where NULL means the default, and others are parsed in a file - dependent way. The result of this function is handed in to sym_read. */ - - struct section_offsets *(*sym_offsets) PARAMS ((struct objfile *, CORE_ADDR)); - - /* Finds the next struct sym_fns. They are allocated and initialized - in whatever module implements the functions pointed to; an - initializer calls add_symtab_fns to add them to the global chain. */ - - struct sym_fns *next; - -}; - -extern void -extend_psymbol_list PARAMS ((struct psymbol_allocation_list *, - struct objfile *)); - -/* Add any kind of symbol to a psymbol_allocation_list. */ - -#ifndef INLINE_ADD_PSYMBOL -#define INLINE_ADD_PSYMBOL 1 -#endif - -#if !INLINE_ADD_PSYMBOL - -/* Since one arg is a struct, we have to pass in a ptr and deref it (sigh) */ - -#define ADD_PSYMBOL_TO_LIST(name, namelength, namespace, class, list, value, language, objfile) \ - add_psymbol_to_list (name, namelength, namespace, class, &list, value, language, objfile) - -#define ADD_PSYMBOL_ADDR_TO_LIST(name, namelength, namespace, class, list, value, language, objfile) \ - add_psymbol_addr_to_list (name, namelength, namespace, class, &list, value, language, objfile) - -#else /* !INLINE_ADD_PSYMBOL */ - -#include "demangle.h" - -#define ADD_PSYMBOL_VT_TO_LIST(NAME,NAMELENGTH,NAMESPACE,CLASS,LIST,VALUE,VT,LANGUAGE, OBJFILE) \ - do { \ - register struct partial_symbol *psym; \ - if ((LIST).next >= (LIST).list + (LIST).size) \ - extend_psymbol_list (&(LIST),(OBJFILE)); \ - psym = (LIST).next++; \ - SYMBOL_NAME (psym) = \ - (char *) obstack_alloc (&objfile->psymbol_obstack, \ - (NAMELENGTH) + 1); \ - memcpy (SYMBOL_NAME (psym), (NAME), (NAMELENGTH)); \ - SYMBOL_NAME (psym)[(NAMELENGTH)] = '\0'; \ - SYMBOL_NAMESPACE (psym) = (NAMESPACE); \ - PSYMBOL_CLASS (psym) = (CLASS); \ - VT (psym) = (VALUE); \ - SYMBOL_LANGUAGE (psym) = (LANGUAGE); \ - SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack); \ - } while (0) - -/* Add a symbol with an integer value to a psymtab. */ - -#define ADD_PSYMBOL_TO_LIST(name, namelength, namespace, class, list, value, language, objfile) \ - ADD_PSYMBOL_VT_TO_LIST (name, namelength, namespace, class, list, value, SYMBOL_VALUE, language, objfile) - -/* Add a symbol with a CORE_ADDR value to a psymtab. */ - -#define ADD_PSYMBOL_ADDR_TO_LIST(name, namelength, namespace, class, list, value, language, objfile)\ - ADD_PSYMBOL_VT_TO_LIST (name, namelength, namespace, class, list, value, SYMBOL_VALUE_ADDRESS, language, objfile) - -#endif /* INLINE_ADD_PSYMBOL */ - - /* Functions */ - -extern void -sort_pst_symbols PARAMS ((struct partial_symtab *)); - -extern struct symtab * -allocate_symtab PARAMS ((char *, struct objfile *)); - -extern int -free_named_symtabs PARAMS ((char *)); - -extern void -fill_in_vptr_fieldno PARAMS ((struct type *)); - -extern void -add_symtab_fns PARAMS ((struct sym_fns *)); - -extern void -init_entry_point_info PARAMS ((struct objfile *)); - -extern void -syms_from_objfile PARAMS ((struct objfile *, CORE_ADDR, int, int)); - -extern void -new_symfile_objfile PARAMS ((struct objfile *, int, int)); - -extern struct partial_symtab * -start_psymtab_common PARAMS ((struct objfile *, struct section_offsets *, - char *, CORE_ADDR, - struct partial_symbol *, - struct partial_symbol *)); - -/* Sorting your symbols for fast lookup or alphabetical printing. */ - -extern void -sort_block_syms PARAMS ((struct block *)); - -extern void -sort_symtab_syms PARAMS ((struct symtab *)); - -/* 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. */ - -extern char * -obsavestring PARAMS ((char *, int, struct obstack *)); - -/* Concatenate strings S1, S2 and S3; return the new string. - Space is found in the symbol_obstack. */ - -extern char * -obconcat PARAMS ((struct obstack *obstackp, const char *, const char *, - const char *)); - - /* Variables */ - -/* From symfile.c */ - -extern struct partial_symtab * -allocate_psymtab PARAMS ((char *, struct objfile *)); - -/* Remote targets may wish to use this as their load function. */ -extern void generic_load PARAMS ((char *name, int from_tty)); - -/* From dwarfread.c */ - -extern void -dwarf_build_psymtabs PARAMS ((struct objfile *, struct section_offsets *, int, - file_ptr, unsigned int, file_ptr, unsigned int)); - -/* From mdebugread.c */ - -/* Hack to force structures to exist before use in parameter list. */ -struct ecoff_debug_hack -{ - struct ecoff_debug_swap *a; - struct ecoff_debug_info *b; -}; -extern void -mdebug_build_psymtabs PARAMS ((struct objfile *, - const struct ecoff_debug_swap *, - struct ecoff_debug_info *, - struct section_offsets *)); - -extern void -elfmdebug_build_psymtabs PARAMS ((struct objfile *, - const struct ecoff_debug_swap *, - asection *, - struct section_offsets *)); - -/* From demangle.c */ - -extern void -set_demangling_style PARAMS ((char *)); - - -/* Stuff shared between coffread.c and xcoffread.c. Eventually we want - to merge coffread.c and xcoffread.c so this part of this header can - go away. */ - -#if 0 -extern char *coff_getfilename PARAMS ((union internal_auxent *)); -#else -/* Don't declare the arguments; if union internal_auxent has not been - declared here, gcc1 will give warnings. */ -extern char *coff_getfilename (); -#endif - -#endif /* !defined(SYMFILE_H) */ diff --git a/gnu/usr.bin/gdb/gdb/symmisc.c b/gnu/usr.bin/gdb/gdb/symmisc.c deleted file mode 100644 index 5b3930f..0000000 --- a/gnu/usr.bin/gdb/gdb/symmisc.c +++ /dev/null @@ -1,988 +0,0 @@ -/* Do various things to symbol tables (other than lookup), for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "bfd.h" -#include "symfile.h" -#include "objfiles.h" -#include "breakpoint.h" -#include "command.h" -#include "obstack.h" -#include "language.h" - -#include - -#ifndef DEV_TTY -#define DEV_TTY "/dev/tty" -#endif - -/* Unfortunately for debugging, stderr is usually a macro. This is painful - when calling functions that take FILE *'s from the debugger. - So we make a variable which has the same value and which is accessible when - debugging GDB with itself. Because stdin et al need not be constants, - we initialize them in the _initialize_symmisc function at the bottom - of the file. */ -FILE *std_in; -FILE *std_out; -FILE *std_err; - -/* Prototypes for local functions */ - -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_msymbols PARAMS ((struct objfile *, GDB_FILE *)); - -static void -dump_objfile PARAMS ((struct objfile *)); - -static int -block_depth PARAMS ((struct block *)); - -static void -print_partial_symbol PARAMS ((struct partial_symbol *, int, char *, GDB_FILE *)); - -struct print_symbol_args { - struct symbol *symbol; - int depth; - GDB_FILE *outfile; -}; - -static int print_symbol PARAMS ((char *)); - -static void -free_symtab_block PARAMS ((struct objfile *, struct block *)); - - -/* Free a struct block <- B and all the symbols defined in that block. */ - -static void -free_symtab_block (objfile, b) - struct objfile *objfile; - struct block *b; -{ - register int i, n; - n = BLOCK_NSYMS (b); - for (i = 0; i < n; i++) - { - mfree (objfile -> md, SYMBOL_NAME (BLOCK_SYM (b, i))); - mfree (objfile -> md, (PTR) BLOCK_SYM (b, i)); - } - mfree (objfile -> md, (PTR) b); -} - -/* Free all the storage associated with the struct symtab <- S. - Note that some symtabs have contents malloc'ed structure by structure, - while some have contents that all live inside one big block of memory, - and some share the contents of another symbol table and so you should - not free the contents on their behalf (except sometimes the linetable, - which maybe per symtab even when the rest is not). - It is s->free_code that says which alternative to use. */ - -void -free_symtab (s) - register struct symtab *s; -{ - register int i, n; - register struct blockvector *bv; - - switch (s->free_code) - { - case free_nothing: - /* All the contents are part of a big block of memory (an obstack), - and some other symtab is in charge of freeing that block. - Therefore, do nothing. */ - break; - - case free_contents: - /* Here all the contents were malloc'ed structure by structure - and must be freed that way. */ - /* First free the blocks (and their symbols. */ - bv = BLOCKVECTOR (s); - n = BLOCKVECTOR_NBLOCKS (bv); - for (i = 0; i < n; i++) - free_symtab_block (s -> objfile, BLOCKVECTOR_BLOCK (bv, i)); - /* Free the blockvector itself. */ - mfree (s -> objfile -> md, (PTR) bv); - /* Also free the linetable. */ - - case free_linetable: - /* Everything will be freed either by our `free_ptr' - or by some other symtab, except for our linetable. - Free that now. */ - if (LINETABLE (s)) - mfree (s -> objfile -> md, (PTR) LINETABLE (s)); - break; - } - - /* If there is a single block of memory to free, free it. */ - if (s -> free_ptr != NULL) - mfree (s -> objfile -> md, s -> free_ptr); - - /* Free source-related stuff */ - if (s -> line_charpos != NULL) - mfree (s -> objfile -> md, (PTR) s -> line_charpos); - if (s -> fullname != NULL) - mfree (s -> objfile -> md, s -> fullname); - mfree (s -> objfile -> md, (PTR) s); -} - -#if MAINTENANCE_CMDS - -static void -dump_objfile (objfile) - struct objfile *objfile; -{ - struct symtab *symtab; - struct partial_symtab *psymtab; - - printf_filtered ("\nObject file %s: ", objfile -> name); - printf_filtered ("Objfile at "); - gdb_print_address (objfile, gdb_stdout); - printf_filtered (", bfd at "); - gdb_print_address (objfile->obfd, gdb_stdout); - printf_filtered (", %d minsyms\n\n", - objfile->minimal_symbol_count); - - if (objfile -> psymtabs) - { - printf_filtered ("Psymtabs:\n"); - for (psymtab = objfile -> psymtabs; - psymtab != NULL; - psymtab = psymtab -> next) - { - printf_filtered ("%s at ", - psymtab -> filename); - gdb_print_address (psymtab, gdb_stdout); - printf_filtered (", "); - if (psymtab -> objfile != objfile) - { - printf_filtered ("NOT ON CHAIN! "); - } - wrap_here (" "); - } - printf_filtered ("\n\n"); - } - - if (objfile -> symtabs) - { - printf_filtered ("Symtabs:\n"); - for (symtab = objfile -> symtabs; - symtab != NULL; - symtab = symtab->next) - { - printf_filtered ("%s at ", symtab -> filename); - gdb_print_address (symtab, gdb_stdout); - printf_filtered (", "); - if (symtab -> objfile != objfile) - { - printf_filtered ("NOT ON CHAIN! "); - } - wrap_here (" "); - } - printf_filtered ("\n\n"); - } -} - -/* Print minimal symbols from this objfile. */ - -static void -dump_msymbols (objfile, outfile) - struct objfile *objfile; - GDB_FILE *outfile; -{ - struct minimal_symbol *msymbol; - int index; - char ms_type; - - fprintf_filtered (outfile, "\nObject file %s:\n\n", objfile -> name); - if (objfile -> minimal_symbol_count == 0) - { - fprintf_filtered (outfile, "No minimal symbols found.\n"); - return; - } - for (index = 0, msymbol = objfile -> msymbols; - SYMBOL_NAME (msymbol) != NULL; msymbol++, index++) - { - switch (msymbol -> type) - { - case mst_unknown: - ms_type = 'u'; - break; - case mst_text: - ms_type = 'T'; - break; - case mst_solib_trampoline: - ms_type = 'S'; - break; - case mst_data: - ms_type = 'D'; - break; - case mst_bss: - ms_type = 'B'; - break; - case mst_abs: - ms_type = 'A'; - break; - case mst_file_text: - ms_type = 't'; - break; - case mst_file_data: - ms_type = 'd'; - break; - case mst_file_bss: - ms_type = 'b'; - break; - default: - ms_type = '?'; - break; - } - fprintf_filtered (outfile, "[%2d] %c %#10lx %s", index, ms_type, - SYMBOL_VALUE_ADDRESS (msymbol), SYMBOL_NAME (msymbol)); - if (SYMBOL_DEMANGLED_NAME (msymbol) != NULL) - { - fprintf_filtered (outfile, " %s", SYMBOL_DEMANGLED_NAME (msymbol)); - } - fputs_filtered ("\n", outfile); - } - if (objfile -> minimal_symbol_count != index) - { - warning ("internal error: minimal symbol count %d != %d", - objfile -> minimal_symbol_count, index); - } - fprintf_filtered (outfile, "\n"); -} - -static void -dump_psymtab (objfile, psymtab, outfile) - struct objfile *objfile; - struct partial_symtab *psymtab; - GDB_FILE *outfile; -{ - int i; - - fprintf_filtered (outfile, "\nPartial symtab for source file %s ", - psymtab -> filename); - fprintf_filtered (outfile, "(object "); - gdb_print_address (psymtab, outfile); - fprintf_filtered (outfile, ")\n\n"); - fprintf_unfiltered (outfile, " Read from object file %s (", - objfile -> name); - gdb_print_address (objfile, outfile); - fprintf_unfiltered (outfile, ")\n"); - - if (psymtab -> readin) - { - fprintf_filtered (outfile, - " Full symtab was read (at "); - gdb_print_address (psymtab->symtab, outfile); - fprintf_filtered (outfile, " by function at "); - gdb_print_address ((PTR)psymtab->read_symtab, outfile); - fprintf_filtered (outfile, ")\n"); - } - - fprintf_filtered (outfile, " Relocate symbols by "); - for (i = 0; i < psymtab->objfile->num_sections; ++i) - { - if (i != 0) - fprintf_filtered (outfile, ", "); - wrap_here (" "); - print_address_numeric (ANOFFSET (psymtab->section_offsets, i), - 1, - outfile); - } - fprintf_filtered (outfile, "\n"); - - fprintf_filtered (outfile, " Symbols cover text addresses "); - print_address_numeric (psymtab->textlow, 1, outfile); - fprintf_filtered (outfile, "-"); - print_address_numeric (psymtab->texthigh, 1, outfile); - fprintf_filtered (outfile, "\n"); - fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n", - psymtab -> number_of_dependencies); - for (i = 0; i < psymtab -> number_of_dependencies; i++) - { - fprintf_filtered (outfile, " %d ", i); - gdb_print_address (psymtab -> dependencies[i], outfile); - fprintf_filtered (outfile, " %s\n", - psymtab -> dependencies[i] -> filename); - } - if (psymtab -> n_global_syms > 0) - { - print_partial_symbol (objfile -> global_psymbols.list - + psymtab -> globals_offset, - psymtab -> n_global_syms, "Global", outfile); - } - if (psymtab -> n_static_syms > 0) - { - print_partial_symbol (objfile -> static_psymbols.list - + psymtab -> statics_offset, - psymtab -> n_static_syms, "Static", outfile); - } - fprintf_filtered (outfile, "\n"); -} - -static void -dump_symtab (objfile, symtab, outfile) - struct objfile *objfile; - struct symtab *symtab; - GDB_FILE *outfile; -{ - register int i, j; - int len, blen; - register struct linetable *l; - struct blockvector *bv; - register struct block *b; - int depth; - - fprintf_filtered (outfile, "\nSymtab for file %s\n", symtab->filename); - 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)); - - /* First print the line table. */ - l = LINETABLE (symtab); - if (l) - { - fprintf_filtered (outfile, "\nLine table:\n\n"); - len = l->nitems; - for (i = 0; i < len; i++) - { - fprintf_filtered (outfile, " line %d at ", l->item[i].line); - print_address_numeric (l->item[i].pc, 1, 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++) - { - 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, " %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, " 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_ERROR); - } - } - fprintf_filtered (outfile, "\n"); -} - -void -maintenance_print_symbols (args, from_tty) - char *args; - int from_tty; -{ - char **argv; - GDB_FILE *outfile; - struct cleanup *cleanups; - char *symname = NULL; - char *filename = DEV_TTY; - struct objfile *objfile; - struct symtab *s; - - dont_repeat (); - - if (args == NULL) - { - error ("\ -Arguments missing: an output file name and an optional symbol file name"); - } - else if ((argv = buildargv (args)) == NULL) - { - nomem (0); - } - cleanups = make_cleanup (freeargv, (char *) argv); - - if (argv[0] != NULL) - { - filename = argv[0]; - /* If a second arg is supplied, it is a source file name to match on */ - if (argv[1] != NULL) - { - symname = argv[1]; - } - } - - filename = tilde_expand (filename); - make_cleanup (free, filename); - - outfile = gdb_fopen (filename, FOPEN_WT); - if (outfile == 0) - perror_with_name (filename); - make_cleanup (fclose, (char *) outfile); - - immediate_quit++; - ALL_SYMTABS (objfile, s) - if (symname == NULL || (STREQ (symname, s -> filename))) - dump_symtab (objfile, s, outfile); - immediate_quit--; - do_cleanups (cleanups); -} - -/* Print symbol ARGS->SYMBOL on ARGS->OUTFILE. ARGS->DEPTH says how - far to indent. ARGS is really a struct print_symbol_args *, but is - declared as char * to get it past catch_errors. Returns 0 for error, - 1 for success. */ - -static int -print_symbol (args) - char *args; -{ - struct symbol *symbol = ((struct print_symbol_args *)args)->symbol; - int depth = ((struct print_symbol_args *)args)->depth; - GDB_FILE *outfile = ((struct print_symbol_args *)args)->outfile; - - print_spaces (depth, outfile); - if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE) - { - fprintf_filtered (outfile, "label %s at ", SYMBOL_SOURCE_NAME (symbol)); - print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile); - fprintf_filtered (outfile, "\n"); - return 1; - } - if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE) - { - if (TYPE_TAG_NAME (SYMBOL_TYPE (symbol))) - { - LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth); - } - else - { - fprintf_filtered (outfile, "%s %s = ", - (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM - ? "enum" - : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT - ? "struct" : "union")), - SYMBOL_NAME (symbol)); - LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth); - } - fprintf_filtered (outfile, ";\n"); - } - else - { - if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF) - fprintf_filtered (outfile, "typedef "); - if (SYMBOL_TYPE (symbol)) - { - /* Print details of types, except for enums where it's clutter. */ - LA_PRINT_TYPE (SYMBOL_TYPE (symbol), SYMBOL_SOURCE_NAME (symbol), - outfile, - TYPE_CODE (SYMBOL_TYPE (symbol)) != TYPE_CODE_ENUM, - depth); - fprintf_filtered (outfile, "; "); - } - else - fprintf_filtered (outfile, "%s ", SYMBOL_SOURCE_NAME (symbol)); - - switch (SYMBOL_CLASS (symbol)) - { - case LOC_CONST: - fprintf_filtered (outfile, "const %ld (0x%lx),", - SYMBOL_VALUE (symbol), - SYMBOL_VALUE (symbol)); - break; - - case LOC_CONST_BYTES: - fprintf_filtered (outfile, "const %u hex bytes:", - TYPE_LENGTH (SYMBOL_TYPE (symbol))); - { - unsigned i; - for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (symbol)); 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, ","); - break; - - case LOC_REGISTER: - fprintf_filtered (outfile, "register %ld,", SYMBOL_VALUE (symbol)); - break; - - case LOC_ARG: - 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,", - SYMBOL_VALUE (symbol)); - break; - - case LOC_REF_ARG: - fprintf_filtered (outfile, "reference arg at 0x%lx,", SYMBOL_VALUE (symbol)); - break; - - case LOC_REGPARM: - fprintf_filtered (outfile, "parameter register %ld,", SYMBOL_VALUE (symbol)); - break; - - case LOC_REGPARM_ADDR: - fprintf_filtered (outfile, "address parameter register %ld,", SYMBOL_VALUE (symbol)); - break; - - case LOC_LOCAL: - fprintf_filtered (outfile, "local at offset 0x%lx,", - SYMBOL_VALUE (symbol)); - break; - - case LOC_BASEREG: - fprintf_filtered (outfile, "local at 0x%lx from register %d", - SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol)); - break; - - case LOC_BASEREG_ARG: - fprintf_filtered (outfile, "arg at 0x%lx from register %d,", - SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol)); - break; - - case LOC_TYPEDEF: - break; - - case LOC_LABEL: - fprintf_filtered (outfile, "label at "); - print_address_numeric (SYMBOL_VALUE_ADDRESS (symbol), 1, outfile); - break; - - case LOC_BLOCK: - fprintf_filtered (outfile, "block (object "); - gdb_print_address (SYMBOL_BLOCK_VALUE (symbol), outfile); - fprintf_filtered (outfile, ") starting at "); - print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)), - 1, - outfile); - fprintf_filtered (outfile, ","); - break; - - case LOC_OPTIMIZED_OUT: - fprintf_filtered (outfile, "optimized out"); - break; - - default: - fprintf_filtered (outfile, "botched symbol class %x", - SYMBOL_CLASS (symbol)); - break; - } - } - fprintf_filtered (outfile, "\n"); - return 1; -} - -void -maintenance_print_psymbols (args, from_tty) - char *args; - int from_tty; -{ - char **argv; - GDB_FILE *outfile; - struct cleanup *cleanups; - char *symname = NULL; - char *filename = DEV_TTY; - struct objfile *objfile; - struct partial_symtab *ps; - - dont_repeat (); - - if (args == NULL) - { - error ("print-psymbols takes an output file name and optional symbol file name"); - } - else if ((argv = buildargv (args)) == NULL) - { - nomem (0); - } - cleanups = make_cleanup (freeargv, (char *) argv); - - if (argv[0] != NULL) - { - filename = argv[0]; - /* If a second arg is supplied, it is a source file name to match on */ - if (argv[1] != NULL) - { - symname = argv[1]; - } - } - - filename = tilde_expand (filename); - make_cleanup (free, filename); - - outfile = gdb_fopen (filename, FOPEN_WT); - if (outfile == 0) - perror_with_name (filename); - make_cleanup (fclose, outfile); - - immediate_quit++; - ALL_PSYMTABS (objfile, ps) - if (symname == NULL || (STREQ (symname, ps -> filename))) - dump_psymtab (objfile, ps, outfile); - immediate_quit--; - do_cleanups (cleanups); -} - -static void -print_partial_symbol (p, count, what, outfile) - struct partial_symbol *p; - int count; - char *what; - GDB_FILE *outfile; -{ - - fprintf_filtered (outfile, " %s partial symbols:\n", what); - while (count-- > 0) - { - fprintf_filtered (outfile, " `%s'", SYMBOL_NAME(p)); - if (SYMBOL_DEMANGLED_NAME (p) != NULL) - { - fprintf_filtered (outfile, " `%s'", SYMBOL_DEMANGLED_NAME (p)); - } - fputs_filtered (", ", outfile); - switch (SYMBOL_NAMESPACE (p)) - { - case UNDEF_NAMESPACE: - fputs_filtered ("undefined namespace, ", outfile); - break; - case VAR_NAMESPACE: - /* This is the usual thing -- don't print it */ - break; - case STRUCT_NAMESPACE: - fputs_filtered ("struct namespace, ", outfile); - break; - case LABEL_NAMESPACE: - fputs_filtered ("label namespace, ", outfile); - break; - default: - fputs_filtered (", ", outfile); - break; - } - switch (SYMBOL_CLASS (p)) - { - case LOC_UNDEF: - fputs_filtered ("undefined", outfile); - break; - case LOC_CONST: - fputs_filtered ("constant int", outfile); - break; - case LOC_STATIC: - fputs_filtered ("static", outfile); - break; - case LOC_REGISTER: - fputs_filtered ("register", outfile); - break; - case LOC_ARG: - fputs_filtered ("pass by value", outfile); - break; - case LOC_REF_ARG: - fputs_filtered ("pass by reference", outfile); - break; - case LOC_REGPARM: - fputs_filtered ("register parameter", outfile); - break; - case LOC_REGPARM_ADDR: - fputs_filtered ("register address parameter", outfile); - break; - case LOC_LOCAL: - fputs_filtered ("stack parameter", outfile); - break; - case LOC_TYPEDEF: - fputs_filtered ("type", outfile); - break; - case LOC_LABEL: - fputs_filtered ("label", outfile); - break; - case LOC_BLOCK: - fputs_filtered ("function", outfile); - break; - case LOC_CONST_BYTES: - fputs_filtered ("constant bytes", outfile); - break; - case LOC_LOCAL_ARG: - fputs_filtered ("shuffled arg", outfile); - break; - case LOC_OPTIMIZED_OUT: - fputs_filtered ("optimized out", outfile); - break; - default: - fputs_filtered ("", 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)); - p++; - } -} - -void -maintenance_print_msymbols (args, from_tty) - char *args; - int from_tty; -{ - char **argv; - GDB_FILE *outfile; - struct cleanup *cleanups; - char *filename = DEV_TTY; - char *symname = NULL; - struct objfile *objfile; - - dont_repeat (); - - if (args == NULL) - { - error ("print-msymbols takes an output file name and optional symbol file name"); - } - else if ((argv = buildargv (args)) == NULL) - { - nomem (0); - } - cleanups = make_cleanup (freeargv, argv); - - if (argv[0] != NULL) - { - filename = argv[0]; - /* If a second arg is supplied, it is a source file name to match on */ - if (argv[1] != NULL) - { - symname = argv[1]; - } - } - - filename = tilde_expand (filename); - make_cleanup (free, filename); - - outfile = gdb_fopen (filename, FOPEN_WT); - if (outfile == 0) - perror_with_name (filename); - make_cleanup (fclose, outfile); - - immediate_quit++; - ALL_OBJFILES (objfile) - if (symname == NULL || (STREQ (symname, objfile -> name))) - dump_msymbols (objfile, outfile); - immediate_quit--; - fprintf_filtered (outfile, "\n\n"); - do_cleanups (cleanups); -} - -void -maintenance_print_objfiles (ignore, from_tty) - char *ignore; - int from_tty; -{ - struct objfile *objfile; - - dont_repeat (); - - immediate_quit++; - ALL_OBJFILES (objfile) - dump_objfile (objfile); - immediate_quit--; -} - -/* Check consistency of psymtabs and symtabs. */ - -void -maintenance_check_symtabs (ignore, from_tty) - char *ignore; - int from_tty; -{ - register struct symbol *sym; - register struct partial_symbol *psym; - register struct symtab *s = NULL; - register struct partial_symtab *ps; - struct blockvector *bv; - register struct objfile *objfile; - register struct block *b; - int length; - - ALL_PSYMTABS (objfile, ps) - { - s = PSYMTAB_TO_SYMTAB(ps); - if (s == NULL) - continue; - bv = BLOCKVECTOR (s); - b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - psym = ps->objfile->static_psymbols.list + ps->statics_offset; - length = ps->n_static_syms; - while (length--) - { - sym = lookup_block_symbol (b, SYMBOL_NAME (psym), - SYMBOL_NAMESPACE (psym)); - if (!sym) - { - printf_filtered ("Static symbol `"); - puts_filtered (SYMBOL_NAME (psym)); - printf_filtered ("' only found in "); - puts_filtered (ps->filename); - printf_filtered (" psymtab\n"); - } - psym++; - } - b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - psym = ps->objfile->global_psymbols.list + ps->globals_offset; - length = ps->n_global_syms; - while (length--) - { - sym = lookup_block_symbol (b, SYMBOL_NAME (psym), - SYMBOL_NAMESPACE (psym)); - if (!sym) - { - printf_filtered ("Global symbol `"); - puts_filtered (SYMBOL_NAME (psym)); - printf_filtered ("' only found in "); - puts_filtered (ps->filename); - printf_filtered (" psymtab\n"); - } - psym++; - } - if (ps->texthigh < ps->textlow) - { - printf_filtered ("Psymtab "); - puts_filtered (ps->filename); - printf_filtered (" covers bad range "); - print_address_numeric (ps->textlow, 1, stdout); - printf_filtered (" - "); - print_address_numeric (ps->texthigh, 1, stdout); - printf_filtered ("\n"); - continue; - } - if (ps->texthigh == 0) - continue; - if (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b)) - { - printf_filtered ("Psymtab "); - puts_filtered (ps->filename); - printf_filtered (" covers "); - print_address_numeric (ps->textlow, 1, stdout); - printf_filtered (" - "); - print_address_numeric (ps->texthigh, 1, stdout); - printf_filtered (" but symtab covers only "); - print_address_numeric (BLOCK_START (b), 1, stdout); - printf_filtered (" - "); - print_address_numeric (BLOCK_END (b), 1, stdout); - printf_filtered ("\n"); - } - } -} - - -/* Return the nexting depth of a block within other blocks in its symtab. */ - -static int -block_depth (block) - struct block *block; -{ - register int i = 0; - while ((block = BLOCK_SUPERBLOCK (block)) != NULL) - { - i++; - } - return i; -} - -#endif /* MAINTENANCE_CMDS */ - - -/* Increase the space allocated for LISTP, which is probably - global_psymbol_list or static_psymbol_list. This space will eventually - be freed in free_objfile(). */ - -void -extend_psymbol_list (listp, objfile) - register struct psymbol_allocation_list *listp; - struct objfile *objfile; -{ - int new_size; - if (listp->size == 0) - { - new_size = 255; - listp->list = (struct partial_symbol *) - xmmalloc (objfile -> md, new_size * sizeof (struct partial_symbol)); - } - else - { - new_size = listp->size * 2; - listp->list = (struct partial_symbol *) - xmrealloc (objfile -> md, (char *) listp->list, - new_size * sizeof (struct partial_symbol)); - } - /* Next assumes we only went one over. Should be good if - program works correctly */ - listp->next = listp->list + listp->size; - listp->size = new_size; -} - - -/* Do early runtime initializations. */ -void -_initialize_symmisc () -{ - std_in = stdin; - std_out = stdout; - std_err = stderr; -} diff --git a/gnu/usr.bin/gdb/gdb/symtab.c b/gnu/usr.bin/gdb/gdb/symtab.c deleted file mode 100644 index eab46ce..0000000 --- a/gnu/usr.bin/gdb/gdb/symtab.c +++ /dev/null @@ -1,3251 +0,0 @@ -/* Symbol table lookup for the GNU debugger, GDB. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 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. */ - -#include "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "gdbcore.h" -#include "frame.h" -#include "target.h" -#include "value.h" -#include "symfile.h" -#include "objfiles.h" -#include "gdbcmd.h" -#include "call-cmds.h" -#include "gnuregex.h" -#include "expression.h" -#include "language.h" -#include "demangle.h" - -#include - -#include -#include -#include -#include -#include - -/* Prototypes for local functions */ - -extern int -find_methods PARAMS ((struct type *, char *, struct symbol **)); - -static void -completion_list_add_name PARAMS ((char *, char *, int, char *, char *)); - -static void -build_canonical_line_spec PARAMS ((struct symtab_and_line *, char *, char ***)); - -static struct symtabs_and_lines -decode_line_2 PARAMS ((struct symbol *[], int, int, char ***)); - -static void -rbreak_command PARAMS ((char *, int)); - -static void -types_info PARAMS ((char *, int)); - -static void -functions_info PARAMS ((char *, int)); - -static void -variables_info PARAMS ((char *, int)); - -static void -sources_info PARAMS ((char *, int)); - -static void -list_symbols PARAMS ((char *, int, int, int)); - -static void -output_source_filename PARAMS ((char *, int *)); - -static 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, enum namespace)); - -static struct symtab * -lookup_symtab_1 PARAMS ((char *)); - -/* */ - -/* The single non-language-specific builtin type */ -struct type *builtin_type_error; - -/* Block in which the most recently searched-for symbol was found. - Might be better to make this a parameter to lookup_symbol and - value_of_this. */ - -const struct block *block_found; - -char no_symtab_msg[] = "No symbol table is loaded. Use the \"file\" command."; - -/* While the C++ support is still in flux, issue a possibly helpful hint on - using the new command completion feature on single quoted demangled C++ - symbols. Remove when loose ends are cleaned up. FIXME -fnf */ - -void -cplusplus_hint (name) - char *name; -{ - printf_filtered ("Hint: try '%s or '%s\n", name, name); - printf_filtered ("(Note leading single quote.)\n"); -} - -/* Check for a symtab of a specific name; first in symtabs, then in - psymtabs. *If* there is no '/' in the name, a match after a '/' - in the symtab filename will also work. */ - -static struct symtab * -lookup_symtab_1 (name) - char *name; -{ - register struct symtab *s; - register struct partial_symtab *ps; - register char *slash; - register struct objfile *objfile; - - got_symtab: - - /* First, search for an exact match */ - - ALL_SYMTABS (objfile, s) - if (STREQ (name, s->filename)) - return s; - - slash = strchr (name, '/'); - - /* Now, search for a matching tail (only if name doesn't have any dirs) */ - - if (!slash) - ALL_SYMTABS (objfile, s) - { - char *p = s -> filename; - char *tail = strrchr (p, '/'); - - if (tail) - p = tail + 1; - - if (STREQ (p, name)) - return s; - } - - /* Same search rules as above apply here, but now we look thru the - psymtabs. */ - - ps = lookup_partial_symtab (name); - if (!ps) - return (NULL); - - if (ps -> readin) - error ("Internal: readin %s pst for `%s' found when no symtab found.", - ps -> filename, name); - - s = PSYMTAB_TO_SYMTAB (ps); - - if (s) - return s; - - /* At this point, we have located the psymtab for this file, but - the conversion to a symtab has failed. This usually happens - when we are looking up an include file. In this case, - PSYMTAB_TO_SYMTAB doesn't return a symtab, even though one has - been created. So, we need to run through the symtabs again in - order to find the file. - XXX - This is a crock, and should be fixed inside of the the - symbol parsing routines. */ - goto got_symtab; -} - -/* Lookup the symbol table of a source file named NAME. Try a couple - of variations if the first lookup doesn't work. */ - -struct symtab * -lookup_symtab (name) - char *name; -{ - register struct symtab *s; -#if 0 - register char *copy; -#endif - - s = lookup_symtab_1 (name); - if (s) return s; - -#if 0 - /* This screws c-exp.y:yylex if there is both a type "tree" and a symtab - "tree.c". */ - - /* If name not found as specified, see if adding ".c" helps. */ - /* Why is this? Is it just a user convenience? (If so, it's pretty - questionable in the presence of C++, FORTRAN, etc.). It's not in - the GDB manual. */ - - copy = (char *) alloca (strlen (name) + 3); - strcpy (copy, name); - strcat (copy, ".c"); - s = lookup_symtab_1 (copy); - if (s) return s; -#endif /* 0 */ - - /* We didn't find anything; die. */ - return 0; -} - -/* Lookup the partial symbol table of a source file named NAME. - *If* there is no '/' in the name, a match after a '/' - in the psymtab filename will also work. */ - -struct partial_symtab * -lookup_partial_symtab (name) -char *name; -{ - register struct partial_symtab *pst; - register struct objfile *objfile; - - ALL_PSYMTABS (objfile, pst) - { - if (STREQ (name, pst -> filename)) - { - return (pst); - } - } - - /* Now, search for a matching tail (only if name doesn't have any dirs) */ - - if (!strchr (name, '/')) - ALL_PSYMTABS (objfile, pst) - { - char *p = pst -> filename; - char *tail = strrchr (p, '/'); - - if (tail) - p = tail + 1; - - if (STREQ (p, name)) - return (pst); - } - - return (NULL); -} - -/* Demangle a GDB method stub type. - Note that this function is g++ specific. */ - -char * -gdb_mangle_name (type, i, j) - struct type *type; - int i, j; -{ - 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); - char *newname = type_name_no_tag (type); - - /* Does the form of physname indicate that it is the full mangled name - of a constructor (not just the args)? */ - int is_full_physname_constructor; - - int is_constructor; - int is_destructor = DESTRUCTOR_PREFIX_P (physname); - /* Need a new type prefix. */ - char *const_prefix = method->is_const ? "C" : ""; - char *volatile_prefix = method->is_volatile ? "V" : ""; - char buf[20]; - int len = (newname == NULL ? 0 : strlen (newname)); - - is_full_physname_constructor = - ((physname[0]=='_' && physname[1]=='_' && - (isdigit(physname[2]) || physname[2]=='Q' || physname[2]=='t')) - || (strncmp(physname, "__ct", 4) == 0)); - - is_constructor = - is_full_physname_constructor || (newname && STREQ(field_name, newname)); - - if (!is_destructor) - is_destructor = (strncmp(physname, "__dt", 4) == 0); - -#ifndef GCC_MANGLE_BUG - if (is_destructor || is_full_physname_constructor) - { - mangled_name = (char*) xmalloc(strlen(physname)+1); - strcpy(mangled_name, physname); - return mangled_name; - } - - if (len == 0) - { - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - if (strcmp(buf, "__") == 0) - buf[0] = '\0'; - } - else - { - sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len); - } - mangled_name_len = ((is_constructor ? 0 : strlen (field_name)) - + strlen (buf) + len - + strlen (physname) - + 1); - - /* Only needed for GNU-mangled names. ANSI-mangled names - work with the normal mechanisms. */ - if (OPNAME_PREFIX_P (field_name)) - { - char *opname = cplus_mangle_opname (field_name + 3, 0); - if (opname == NULL) - error ("No mangling for \"%s\"", field_name); - mangled_name_len += strlen (opname); - mangled_name = (char *)xmalloc (mangled_name_len); - - strncpy (mangled_name, field_name, 3); - mangled_name[3] = '\0'; - strcat (mangled_name, opname); - } - else - { - mangled_name = (char *)xmalloc (mangled_name_len); - if (is_constructor) - mangled_name[0] = '\0'; - else - strcpy (mangled_name, field_name); - } - strcat (mangled_name, buf); - /* If the class doesn't have a name, i.e. newname NULL, then we just - mangle it using 0 for the length of the class. Thus it gets mangled - as something starting with `::' rather than `classname::'. */ - if (newname != NULL) - strcat (mangled_name, newname); - -#else - - if (is_constructor) - { - buf[0] = '\0'; - } - else - { - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - } - - mangled_name_len = ((is_constructor ? 0 : strlen (field_name)) - + strlen (buf) + strlen (physname) + 1); - - /* Only needed for GNU-mangled names. ANSI-mangled names - work with the normal mechanisms. */ - if (OPNAME_PREFIX_P (field_name)) - { - char *opname; - opname = cplus_mangle_opname (field_name + 3, 0); - if (opname == NULL) - { - error ("No mangling for \"%s\"", field_name); - } - mangled_name_len += strlen (opname); - mangled_name = (char *) xmalloc (mangled_name_len); - - strncpy (mangled_name, field_name, 3); - strcpy (mangled_name + 3, opname); - } - else - { - mangled_name = (char *) xmalloc (mangled_name_len); - if (is_constructor) - { - mangled_name[0] = '\0'; - } - else - { - strcpy (mangled_name, field_name); - } - } - strcat (mangled_name, buf); - -#endif - strcat (mangled_name, physname); - return (mangled_name); -} - - -/* Find which partial symtab on contains PC. Return 0 if none. */ - -struct partial_symtab * -find_pc_psymtab (pc) - register CORE_ADDR pc; -{ - register struct partial_symtab *pst; - register struct objfile *objfile; - - ALL_PSYMTABS (objfile, pst) - { - if (pc >= pst->textlow && pc < pst->texthigh) - return (pst); - } - return (NULL); -} - -/* Find which partial symbol within a psymtab contains PC. Return 0 - if none. Check all psymtabs if PSYMTAB is 0. */ -struct partial_symbol * -find_pc_psymbol (psymtab, pc) - struct partial_symtab *psymtab; - CORE_ADDR pc; -{ - struct partial_symbol *best = NULL, *p; - CORE_ADDR best_pc; - - if (!psymtab) - psymtab = find_pc_psymtab (pc); - if (!psymtab) - return 0; - - best_pc = psymtab->textlow - 1; - - /* Search the global symbols as well as the static symbols, so that - find_pc_partial_function doesn't use a minimal symbol and thus - cache a bad endaddr. */ - for (p = psymtab->objfile->global_psymbols.list + psymtab->globals_offset; - (p - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset) - < psymtab->n_global_syms); - p++) - if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE - && SYMBOL_CLASS (p) == LOC_BLOCK - && pc >= SYMBOL_VALUE_ADDRESS (p) - && SYMBOL_VALUE_ADDRESS (p) > best_pc) - { - best_pc = SYMBOL_VALUE_ADDRESS (p); - best = p; - } - for (p = psymtab->objfile->static_psymbols.list + psymtab->statics_offset; - (p - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset) - < psymtab->n_static_syms); - p++) - if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE - && SYMBOL_CLASS (p) == LOC_BLOCK - && pc >= SYMBOL_VALUE_ADDRESS (p) - && SYMBOL_VALUE_ADDRESS (p) > best_pc) - { - best_pc = SYMBOL_VALUE_ADDRESS (p); - best = p; - } - if (best_pc == psymtab->textlow - 1) - return 0; - return best; -} - - -/* 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. - If SYMTAB is non-NULL, store the symbol table in which the - symbol was found there, or NULL if not found. - C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if - NAME is a field of the current implied argument `this'. If so set - *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero. - BLOCK_FOUND is set to the block in which NAME is found (in the case of - a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */ - -/* This function has a bunch of loops in it and it would seem to be - attractive to put in some QUIT's (though I'm not really sure - whether it can run long enough to be really important). But there - are a few calls for which it would appear to be bad news to quit - out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c, and - nindy_frame_chain_valid in nindy-tdep.c. (Note that there is C++ - code below which can error(), but that probably doesn't affect - these calls since they are looking for a known variable and thus - can probably assume it will never hit the C++ code). */ - -struct symbol * -lookup_symbol (name, block, namespace, is_a_field_of_this, symtab) - const char *name; - register const struct block *block; - const enum namespace namespace; - int *is_a_field_of_this; - struct symtab **symtab; -{ - register struct symbol *sym; - register struct symtab *s = NULL; - register struct partial_symtab *ps; - struct blockvector *bv; - register struct objfile *objfile; - register struct block *b; - register struct minimal_symbol *msymbol; - - /* Search specified block and its superiors. */ - - while (block != 0) - { - sym = lookup_block_symbol (block, name, namespace); - if (sym) - { - block_found = block; - if (symtab != NULL) - { - /* Search the list of symtabs for one which contains the - address of the start of this block. */ - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - if (BLOCK_START (b) <= BLOCK_START (block) - && BLOCK_END (b) > BLOCK_START (block)) - goto found; - } -found: - *symtab = s; - } - - return (sym); - } - block = BLOCK_SUPERBLOCK (block); - } - - /* FIXME: this code is never executed--block is always NULL at this - point. What is it trying to do, anyway? We already should have - checked the STATIC_BLOCK above (it is the superblock of top-level - blocks). Why is VAR_NAMESPACE special-cased? */ - /* 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. */ - if (namespace == VAR_NAMESPACE && block != NULL) - { - struct block *b; - /* Find the right symtab. */ - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - if (BLOCK_START (b) <= BLOCK_START (block) - && BLOCK_END (b) > BLOCK_START (block)) - { - sym = lookup_block_symbol (b, name, VAR_NAMESPACE); - if (sym) - { - block_found = b; - if (symtab != NULL) - *symtab = s; - return sym; - } - } - } - } - - - /* C++: If requested to do so by the caller, - check to see if NAME is a field of `this'. */ - if (is_a_field_of_this) - { - struct value *v = value_of_this (0); - - *is_a_field_of_this = 0; - if (v && check_field (v, name)) - { - *is_a_field_of_this = 1; - if (symtab != NULL) - *symtab = NULL; - return 0; - } - } - - /* Now search all global blocks. Do the symtab's first, then - check the psymtab's */ - - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, namespace); - if (sym) - { - block_found = block; - if (symtab != NULL) - *symtab = s; - return sym; - } - } - - /* Check for the possibility of the symbol being a global function - that is stored in one of the minimal symbol tables. Eventually, all - global symbols might be resolved in this way. */ - - if (namespace == VAR_NAMESPACE) - { - msymbol = lookup_minimal_symbol (name, (struct objfile *) NULL); - if (msymbol != NULL) - { - s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)); - /* If S is NULL, there are no debug symbols for this file. - Skip this stuff and check for matching static symbols below. */ - 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); - } - - /* sym == 0 if symbol was found in the minimal symbol table - but not in the symtab. - Return 0 to use the msymbol definition of "foo_". - - 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 (symtab != NULL) - *symtab = s; - return sym; - } - } - } - - ALL_PSYMTABS (objfile, ps) - { - if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace)) - { - s = PSYMTAB_TO_SYMTAB(ps); - bv = BLOCKVECTOR (s); - 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); - if (symtab != NULL) - *symtab = s; - return sym; - } - } - - /* Now search all per-file blocks. - Not strictly correct, but more useful than an error. - Do the symtabs first, then check the psymtabs */ - - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, namespace); - if (sym) - { - block_found = block; - if (symtab != NULL) - *symtab = s; - return sym; - } - } - - ALL_PSYMTABS (objfile, ps) - { - if (!ps->readin && lookup_partial_symbol (ps, name, 0, namespace)) - { - s = PSYMTAB_TO_SYMTAB(ps); - bv = BLOCKVECTOR (s); - 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); - if (symtab != NULL) - *symtab = s; - return sym; - } - } - - /* Now search all per-file blocks for static mangled symbols. - Do the symtabs first, then check the psymtabs. */ - - if (namespace == VAR_NAMESPACE) - { - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, VAR_NAMESPACE); - if (sym) - { - block_found = block; - if (symtab != NULL) - *symtab = s; - return sym; - } - } - - ALL_PSYMTABS (objfile, ps) - { - if (!ps->readin && lookup_partial_symbol (ps, name, 0, VAR_NAMESPACE)) - { - s = PSYMTAB_TO_SYMTAB(ps); - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, VAR_NAMESPACE); - if (!sym) - error ("Internal: mangled static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename); - if (symtab != NULL) - *symtab = s; - return sym; - } - } - } - - if (symtab != NULL) - *symtab = NULL; - return 0; -} - -/* Look, in partial_symtab PST, for symbol NAME. Check the global - symbols if GLOBAL, the static symbols if not */ - -static struct partial_symbol * -lookup_partial_symbol (pst, name, global, namespace) - struct partial_symtab *pst; - const char *name; - int global; - enum namespace namespace; -{ - struct partial_symbol *start, *psym; - struct partial_symbol *top, *bottom, *center; - int length = (global ? pst->n_global_syms : pst->n_static_syms); - int do_linear_search = 1; - - if (length == 0) - { - return (NULL); - } - - start = (global ? - pst->objfile->global_psymbols.list + pst->globals_offset : - pst->objfile->static_psymbols.list + pst->statics_offset ); - - if (global) /* This means we can use a binary search. */ - { - do_linear_search = 0; - - /* Binary search. This search is guaranteed to end with center - pointing at the earliest partial symbol with the correct - name. At that point *all* partial symbols with that name - will be checked against the correct namespace. */ - - bottom = start; - top = start + length - 1; - while (top > bottom) - { - center = bottom + (top - bottom) / 2; - if (!(center < top)) - abort (); - if (!do_linear_search && SYMBOL_LANGUAGE (center) == language_cplus) - { - do_linear_search = 1; - } - if (STRCMP (SYMBOL_NAME (center), name) >= 0) - { - top = center; - } - else - { - bottom = center + 1; - } - } - if (!(top == bottom)) - abort (); - while (STREQ (SYMBOL_NAME (top), name)) - { - if (SYMBOL_NAMESPACE (top) == namespace) - { - return top; - } - top ++; - } - } - - /* Can't use a binary search or else we found during the binary search that - we should also do a linear search. */ - - if (do_linear_search) - { - for (psym = start; psym < start + length; psym++) - { - if (namespace == SYMBOL_NAMESPACE (psym)) - { - if (SYMBOL_MATCHES_NAME (psym, name)) - { - return (psym); - } - } - } - } - - return (NULL); -} - -/* Find the psymtab containing main(). */ -/* FIXME: What about languages without main() or specially linked - executables that have no main() ? */ - -struct partial_symtab * -find_main_psymtab () -{ - register struct partial_symtab *pst; - register struct objfile *objfile; - - ALL_PSYMTABS (objfile, pst) - { - if (lookup_partial_symbol (pst, "main", 1, VAR_NAMESPACE)) - { - return (pst); - } - } - return (NULL); -} - -/* Search BLOCK for symbol NAME in NAMESPACE. - - Note that if NAME is the demangled form of a C++ symbol, we will fail - to find a match during the binary search of the non-encoded names, but - for now we don't worry about the slight inefficiency of looking for - a match we'll never find, since it will go pretty quick. Once the - binary search terminates, we drop through and do a straight linear - search on the symbols. Each symbol which is marked as being a C++ - symbol (language_cplus set) has both the encoded and non-encoded names - tested for a match. */ - -struct symbol * -lookup_block_symbol (block, name, namespace) - register const struct block *block; - const char *name; - const enum namespace namespace; -{ - register int bot, top, inc; - register struct symbol *sym; - register struct symbol *sym_found = NULL; - register int do_linear_search = 1; - - /* If the blocks's symbols were sorted, start with a binary search. */ - - if (BLOCK_SHOULD_SORT (block)) - { - /* Reset the linear search flag so if the binary search fails, we - won't do the linear search once unless we find some reason to - do so, such as finding a C++ symbol during the binary search. - Note that for C++ modules, ALL the symbols in a block should - end up marked as C++ symbols. */ - - do_linear_search = 0; - top = BLOCK_NSYMS (block); - bot = 0; - - /* Advance BOT to not far before the first symbol whose name is NAME. */ - - while (1) - { - inc = (top - bot + 1); - /* No need to keep binary searching for the last few bits worth. */ - if (inc < 4) - { - break; - } - inc = (inc >> 1) + bot; - sym = BLOCK_SYM (block, inc); - if (!do_linear_search && SYMBOL_LANGUAGE (sym) == language_cplus) - { - do_linear_search = 1; - } - if (SYMBOL_NAME (sym)[0] < name[0]) - { - bot = inc; - } - else if (SYMBOL_NAME (sym)[0] > name[0]) - { - top = inc; - } - else if (STRCMP (SYMBOL_NAME (sym), name) < 0) - { - bot = inc; - } - else - { - top = inc; - } - } - - /* Now scan forward until we run out of symbols, find one whose - name is greater than NAME, or find one we want. If there is - more than one symbol with the right name and namespace, we - return the first one; I believe it is now impossible for us - to encounter two symbols with the same name and namespace - here, because blocks containing argument symbols are no - longer sorted. */ - - top = BLOCK_NSYMS (block); - while (bot < top) - { - sym = BLOCK_SYM (block, bot); - inc = SYMBOL_NAME (sym)[0] - name[0]; - if (inc == 0) - { - inc = STRCMP (SYMBOL_NAME (sym), name); - } - if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace) - { - return (sym); - } - if (inc > 0) - { - break; - } - bot++; - } - } - - /* Here if block isn't sorted, or we fail to find a match during the - binary search above. If during the binary search above, we find a - symbol which is a C++ symbol, then we have re-enabled the linear - search flag which was reset when starting the binary search. - - This loop is equivalent to the loop above, but hacked greatly for speed. - - Note that parameter symbols do not always show up last in the - list; this loop makes sure to take anything else other than - parameter symbols first; it only uses parameter symbols as a - last resort. Note that this only takes up extra computation - time on a match. */ - - if (do_linear_search) - { - top = BLOCK_NSYMS (block); - bot = 0; - while (bot < top) - { - sym = BLOCK_SYM (block, bot); - if (SYMBOL_NAMESPACE (sym) == namespace && - SYMBOL_MATCHES_NAME (sym, name)) - { - sym_found = sym; - if (SYMBOL_CLASS (sym) != LOC_ARG && - SYMBOL_CLASS (sym) != LOC_LOCAL_ARG && - SYMBOL_CLASS (sym) != LOC_REF_ARG && - SYMBOL_CLASS (sym) != LOC_REGPARM && - SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR && - SYMBOL_CLASS (sym) != LOC_BASEREG_ARG) - { - break; - } - } - bot++; - } - } - return (sym_found); /* Will be NULL if not found. */ -} - - -/* Return the symbol for the function which contains a specified - lexical block, described by a struct block BL. */ - -struct symbol * -block_function (bl) - struct block *bl; -{ - while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0) - bl = BLOCK_SUPERBLOCK (bl); - - return BLOCK_FUNCTION (bl); -} - -/* Find the symtab associated with PC. Look through the psymtabs and read in - another symtab if necessary. */ - -struct symtab * -find_pc_symtab (pc) - register CORE_ADDR pc; -{ - register struct block *b; - struct blockvector *bv; - register struct symtab *s = NULL; - register struct symtab *best_s = NULL; - register struct partial_symtab *ps; - register struct objfile *objfile; - int 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 - to deal with a case like symtab a is at 0x1000-0x2000 and 0x3000-0x4000 - and symtab b is at 0x2000-0x3000. So the GLOBAL_BLOCK for a is from - 0x1000-0x4000, but for address 0x2345 we want to return symtab b. - This is said to happen for the mips; it might be swifter to create - several symtabs with the same name like xcoff does (I'm not sure). */ - - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - if (BLOCK_START (b) <= pc - && BLOCK_END (b) > pc - && (distance == 0 - || BLOCK_END (b) - BLOCK_START (b) < distance)) - { - distance = BLOCK_END (b) - BLOCK_START (b); - best_s = s; - } - } - - if (best_s != NULL) - return(best_s); - - s = NULL; - ps = find_pc_psymtab (pc); - if (ps) - { - if (ps->readin) - /* Might want to error() here (in case symtab is corrupt and - will cause a core dump), but maybe we can successfully - continue, so let's not. */ - /* FIXME-32x64: assumes pc fits in a long */ - warning ("\ -(Internal error: pc 0x%lx in read in psymtab, but not in symtab.)\n", - (unsigned long) pc); - s = PSYMTAB_TO_SYMTAB (ps); - } - return (s); -} - -#if 0 - -/* Find the closest symbol value (of any sort -- function or variable) - for a given address value. Slow but complete. (currently unused, - mainly because it is too slow. We could fix it if each symtab and - psymtab had contained in it the addresses ranges of each of its - sections, which also would be required to make things like "info - line *0x2345" cause psymtabs to be converted to symtabs). */ - -struct symbol * -find_addr_symbol (addr, symtabp, symaddrp) - CORE_ADDR addr; - struct symtab **symtabp; - CORE_ADDR *symaddrp; -{ - struct symtab *symtab, *best_symtab; - struct objfile *objfile; - register int bot, top; - register struct symbol *sym; - register CORE_ADDR sym_addr; - struct block *block; - int blocknum; - - /* Info on best symbol seen so far */ - - register CORE_ADDR best_sym_addr = 0; - struct symbol *best_sym = 0; - - /* FIXME -- we should pull in all the psymtabs, too! */ - ALL_SYMTABS (objfile, symtab) - { - /* Search the global and static blocks in this symtab for - the closest symbol-address to the desired address. */ - - for (blocknum = GLOBAL_BLOCK; blocknum <= STATIC_BLOCK; blocknum++) - { - QUIT; - block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum); - top = BLOCK_NSYMS (block); - for (bot = 0; bot < top; bot++) - { - sym = BLOCK_SYM (block, bot); - switch (SYMBOL_CLASS (sym)) - { - case LOC_STATIC: - case LOC_LABEL: - sym_addr = SYMBOL_VALUE_ADDRESS (sym); - break; - - case LOC_BLOCK: - sym_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); - break; - - default: - continue; - } - - if (sym_addr <= addr) - if (sym_addr > best_sym_addr) - { - /* Quit if we found an exact match. */ - best_sym = sym; - best_sym_addr = sym_addr; - best_symtab = symtab; - if (sym_addr == addr) - goto done; - } - } - } - } - - done: - if (symtabp) - *symtabp = best_symtab; - if (symaddrp) - *symaddrp = best_sym_addr; - return best_sym; -} -#endif /* 0 */ - -/* Find the source file and line number for a given PC value. - 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. - NOTCURRENT nonzero means, if specified pc is on a line boundary, - use the line that ends there. Otherwise, in that case, the line - that begins there is used. */ - -/* The big complication here is that a line may start in one file, and end just - before the start of another file. This usually occurs when you #include - code in the middle of a subroutine. To properly find the end of a line's PC - range, we must search all symtabs associated with this compilation unit, and - find the one whose first PC is closer than that of the next line in this - symtab. */ - -/* If it's worth the effort, we could be using a binary search. */ - -struct symtab_and_line -find_pc_line (pc, notcurrent) - CORE_ADDR pc; - int notcurrent; -{ - struct symtab *s; - register struct linetable *l; - register int len; - register int i; - register struct linetable_entry *item; - struct symtab_and_line val; - struct blockvector *bv; - - /* Info on best line seen so far, and where it starts, and its file. */ - - struct linetable_entry *best = NULL; - CORE_ADDR best_end = 0; - struct symtab *best_symtab = 0; - - /* Store here the first line number - of a file which contains the line at the smallest pc after PC. - If we don't find a line whose range contains PC, - we will use a line one less than this, - with a range from the start of that file to the first line's pc. */ - struct linetable_entry *alt = NULL; - struct symtab *alt_symtab = 0; - - /* Info on best line seen in this file. */ - - struct linetable_entry *prev; - - /* If this pc is not from the current frame, - it is the address of the end of a call instruction. - Quite likely that is the start of the following statement. - But what we want is the statement containing the instruction. - Fudge the pc to make sure we get that. */ - - if (notcurrent) pc -= 1; - - s = find_pc_symtab (pc); - if (!s) - { - val.symtab = 0; - val.line = 0; - val.pc = pc; - val.end = 0; - return val; - } - - bv = BLOCKVECTOR (s); - - /* Look at all the symtabs that share this blockvector. - They all have the same apriori range, that we found was right; - but they have different line tables. */ - - for (; s && BLOCKVECTOR (s) == bv; s = s->next) - { - /* Find the best line in this symtab. */ - l = LINETABLE (s); - if (!l) - continue; - len = l->nitems; - if (len <= 0) - { - /* I think len can be zero if the symtab lacks line numbers - (e.g. gcc -g1). (Either that or the LINETABLE is NULL; - I'm not sure which, and maybe it depends on the symbol - reader). */ - continue; - } - - prev = NULL; - item = l->item; /* Get first line info */ - - /* Is this file's first line closer than the first lines of other files? - If so, record this file, and its first line, as best alternate. */ - if (item->pc > pc && (!alt || item->pc < alt->pc)) - { - alt = item; - alt_symtab = s; - } - - for (i = 0; i < len; i++, item++) - { - /* Return the last line that did not start after PC. */ - if (item->pc > pc) - break; - - prev = item; - } - - /* At this point, prev points at the line whose start addr is <= pc, and - item points at the next line. If we ran off the end of the linetable - (pc >= start of the last line), then prev == item. If pc < start of - the first line, prev will not be set. */ - - /* Is this file's best line closer than the best in the other files? - If so, record this file, and its best line, as best so far. */ - - if (prev && (!best || prev->pc > best->pc)) - { - best = prev; - best_symtab = s; - /* If another line is in the linetable, and its PC is closer - than the best_end we currently have, take it as best_end. */ - if (i < len && (best_end == 0 || best_end > item->pc)) - best_end = item->pc; - } - } - - if (!best_symtab) - { - if (!alt_symtab) - { /* If we didn't find any line # info, just - return zeros. */ - val.symtab = 0; - val.line = 0; - val.pc = pc; - val.end = 0; - } - else - { - val.symtab = alt_symtab; - val.line = alt->line - 1; - val.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)); - val.end = alt->pc; - } - } - else - { - val.symtab = best_symtab; - val.line = best->line; - val.pc = best->pc; - if (best_end && (!alt || best_end < alt->pc)) - val.end = best_end; - else if (alt) - val.end = alt->pc; - else - val.end = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)); - } - return val; -} - -static int find_line_symtab PARAMS ((struct symtab *, int, struct linetable **, - 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 - 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. */ - -static int -find_line_symtab (symtab, line, linetable, index, exact_match) - struct symtab *symtab; - int line; - struct linetable **linetable; - int *index; - int *exact_match; -{ - int exact; - - /* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE - so far seen. */ - - int best_index; - struct linetable *best_linetable; - - /* First try looking it up in the given symtab. */ - best_linetable = LINETABLE (symtab); - best_index = find_line_common (best_linetable, line, &exact); - if (best_index < 0 || !exact) - { - /* Didn't find an exact match. So we better keep looking for - another symtab with the same name. In the case of xcoff, - multiple csects for one source file (produced by IBM's FORTRAN - compiler) produce multiple symtabs (this is unavoidable - assuming csects can be at arbitrary places in memory and that - the GLOBAL_BLOCK of a symtab has a begin and end address). */ - - /* BEST is the smallest linenumber > LINE so far seen, - or 0 if none has been seen so far. - BEST_INDEX and BEST_LINETABLE identify the item for it. */ - int best; - - struct objfile *objfile; - struct symtab *s; - - if (best_index >= 0) - best = best_linetable->item[best_index].line; - else - best = 0; - - ALL_SYMTABS (objfile, s) - { - struct linetable *l; - int ind; - - if (!STREQ (symtab->filename, s->filename)) - continue; - l = LINETABLE (s); - ind = find_line_common (l, line, &exact); - if (ind >= 0) - { - if (exact) - { - best_index = ind; - best_linetable = l; - goto done; - } - if (best == 0 || l->item[ind].line < best) - { - best = l->item[ind].line; - best_index = ind; - best_linetable = l; - } - } - } - } - done: - if (best_index < 0) - return 0; - - if (index) - *index = best_index; - if (linetable) - *linetable = best_linetable; - if (exact_match) - *exact_match = exact; - return 1; -} - -/* Find the PC value for a given source file and line number. - Returns zero for invalid line number. - The source file is specified with a struct symtab. */ - -CORE_ADDR -find_line_pc (symtab, line) - struct symtab *symtab; - int line; -{ - struct linetable *l; - int ind; - - if (symtab == 0) - return 0; - if (find_line_symtab (symtab, line, &l, &ind, NULL)) - return l->item[ind].pc; - else - return 0; -} - -/* Find the range of pc values in a line. - Store the starting pc of the line into *STARTPTR - and the ending pc (start of next line) into *ENDPTR. - Returns 1 to indicate success. - Returns 0 if could not find the specified line. */ - -int -find_line_pc_range (sal, startptr, endptr) - struct symtab_and_line sal; - CORE_ADDR *startptr, *endptr; -{ - CORE_ADDR startaddr; - struct symtab_and_line found_sal; - - startaddr = sal.pc; - if (startaddr == 0) - { - startaddr = find_line_pc (sal.symtab, sal.line); - } - if (startaddr == 0) - return 0; - - /* This whole function is based on address. For example, if line 10 has - two parts, one from 0x100 to 0x200 and one from 0x300 to 0x400, then - "info line *0x123" should say the line goes from 0x100 to 0x200 - and "info line *0x355" should say the line goes from 0x300 to 0x400. - This also insures that we never give a range like "starts at 0x134 - and ends at 0x12c". */ - - found_sal = find_pc_line (startaddr, 0); - if (found_sal.line != sal.line) - { - /* The specified line (sal) has zero bytes. */ - *startptr = found_sal.pc; - *endptr = found_sal.pc; - } - else - { - *startptr = found_sal.pc; - *endptr = found_sal.end; - } - return 1; -} - -/* Given a line table and a line number, return the index into the line - table for the pc of the nearest line whose number is >= the specified one. - Return -1 if none is found. The value is >= 0 if it is an index. - - Set *EXACT_MATCH nonzero if the value returned is an exact match. */ - -static int -find_line_common (l, lineno, exact_match) - register struct linetable *l; - register int lineno; - int *exact_match; -{ - register int i; - register int len; - - /* BEST is the smallest linenumber > LINENO so far seen, - or 0 if none has been seen so far. - BEST_INDEX identifies the item for it. */ - - int best_index = -1; - int best = 0; - - if (lineno <= 0) - return -1; - if (l == 0) - return -1; - - len = l->nitems; - for (i = 0; i < len; i++) - { - register struct linetable_entry *item = &(l->item[i]); - - if (item->line == lineno) - { - /* Return the first (lowest address) entry which matches. */ - *exact_match = 1; - return i; - } - - if (item->line > lineno && (best == 0 || item->line < best)) - { - best = item->line; - best_index = i; - } - } - - /* If we got here, we didn't get an exact match. */ - - *exact_match = 0; - return best_index; -} - -int -find_pc_line_pc_range (pc, startptr, endptr) - CORE_ADDR pc; - CORE_ADDR *startptr, *endptr; -{ - struct symtab_and_line sal; - sal = find_pc_line (pc, 0); - *startptr = sal.pc; - *endptr = sal.end; - return sal.symtab != 0; -} - -/* Given a function symbol SYM, find the symtab and line for the start - of the function. - If the argument FUNFIRSTLINE is nonzero, we want the first line - of real code inside the function. */ - -static struct symtab_and_line -find_function_start_sal PARAMS ((struct symbol *sym, int)); - -static struct symtab_and_line -find_function_start_sal (sym, funfirstline) - struct symbol *sym; - int funfirstline; -{ - CORE_ADDR pc; - struct symtab_and_line sal; - - pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); - if (funfirstline) - { - pc += FUNCTION_START_OFFSET; - SKIP_PROLOGUE (pc); - } - sal = find_pc_line (pc, 0); - -#ifdef PROLOGUE_FIRSTLINE_OVERLAP - /* Convex: no need to suppress code on first line, if any */ - sal.pc = pc; -#else - /* Check if SKIP_PROLOGUE left us in mid-line, and the next - line is still part of the same function. */ - if (sal.pc != pc - && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end - && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) - { - /* First pc of next line */ - pc = sal.end; - /* Recalculate the line number (might not be N+1). */ - sal = find_pc_line (pc, 0); - } - sal.pc = pc; -#endif - - return sal; -} - -/* If P is of the form "operator[ \t]+..." where `...' is - some legitimate operator text, return a pointer to the - beginning of the substring of the operator text. - Otherwise, return "". */ -static char * -operator_chars (p, end) - char *p; - char **end; -{ - *end = ""; - if (strncmp (p, "operator", 8)) - return *end; - p += 8; - - /* Don't get faked out by `operator' being part of a longer - identifier. */ - if (isalpha(*p) || *p == '_' || *p == '$' || *p == '\0') - return *end; - - /* Allow some whitespace between `operator' and the operator symbol. */ - while (*p == ' ' || *p == '\t') - p++; - - /* Recognize 'operator TYPENAME'. */ - - if (isalpha(*p) || *p == '_' || *p == '$') - { - register char *q = p+1; - while (isalnum(*q) || *q == '_' || *q == '$') - q++; - *end = q; - return p; - } - - switch (*p) - { - case '!': - case '=': - case '*': - case '/': - case '%': - case '^': - if (p[1] == '=') - *end = p+2; - else - *end = p+1; - return p; - case '<': - case '>': - case '+': - case '-': - case '&': - case '|': - if (p[1] == '=' || p[1] == p[0]) - *end = p+2; - else - *end = p+1; - return p; - case '~': - case ',': - *end = p+1; - return p; - case '(': - if (p[1] != ')') - error ("`operator ()' must be specified without whitespace in `()'"); - *end = p+2; - return p; - case '?': - if (p[1] != ':') - error ("`operator ?:' must be specified without whitespace in `?:'"); - *end = p+2; - return p; - case '[': - if (p[1] != ']') - error ("`operator []' must be specified without whitespace in `[]'"); - *end = p+2; - return p; - default: - error ("`operator %s' not supported", p); - break; - } - *end = ""; - return *end; -} - -/* Recursive helper function for decode_line_1. - * Look for methods named NAME in type T. - * Return number of matches. - * Put matches in SYM_ARR (which better be big enough!). - * These allocations seem to define "big enough": - * sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (t) * sizeof(struct symbol*)); - * Note that this function is g++ specific. - */ - -int -find_methods (t, name, sym_arr) - struct type *t; - char *name; - struct symbol **sym_arr; -{ - int i1 = 0; - 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. */ - if (class_name - && (sym_class = lookup_symbol (class_name, - (struct block *)NULL, - STRUCT_NAMESPACE, - (int *)NULL, - (struct symtab **)NULL))) - { - int method_counter; - /* FIXME: Shouldn't this just be check_stub_type (t)? */ - t = SYMBOL_TYPE (sym_class); - 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)) - method_name = dem_opname; - 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. */ - for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1; - field_counter >= 0; - --field_counter) - { - char *phys_name; - 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); - /* 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, - (int *) NULL, - (struct symtab **) NULL); - 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); - } - } - } - } - - /* Only search baseclasses if there is no match yet, since names in - derived classes override those in baseclasses. - - FIXME: The above is not true; it is only true of member functions - if they have the same number of arguments (??? - section 13.1 of the - ARM says the function members are not in the same scope but doesn't - really spell out the rules in a way I understand. In any case, if - the number of arguments differ this is a case in which we can overload - 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); - return i1; -} - -/* Helper function for decode_line_1. - Build a canonical line spec in CANONICAL if it is non-NULL and if - the SAL has a symtab. - If SYMNAME is non-NULL the canonical line spec is `filename:symname'. - If SYMNAME is NULL the line number from SAL is used and the canonical - line spec is `filename:linenum'. */ - -static void -build_canonical_line_spec (sal, symname, canonical) - struct symtab_and_line *sal; - char *symname; - char ***canonical; -{ - char **canonical_arr; - char *canonical_name; - char *filename; - struct symtab *s = sal->symtab; - - if (s == (struct symtab *)NULL - || s->filename == (char *)NULL - || canonical == (char ***)NULL) - return; - - canonical_arr = (char **) xmalloc (sizeof (char *)); - *canonical = canonical_arr; - - filename = s->filename; - if (symname != NULL) - { - canonical_name = xmalloc (strlen (filename) + strlen (symname) + 2); - sprintf (canonical_name, "%s:%s", filename, symname); - } - else - { - canonical_name = xmalloc (strlen (filename) + 30); - sprintf (canonical_name, "%s:%d", filename, sal->line); - } - canonical_arr[0] = canonical_name; -} - -/* Parse a string that specifies a line number. - Pass the address of a char * variable; that variable will be - advanced over the characters actually parsed. - - The string can be: - - LINENUM -- that line number in current file. PC returned is 0. - FILE:LINENUM -- that line in that file. PC returned is 0. - FUNCTION -- line number of openbrace of that function. - PC returned is the start of the function. - VARIABLE -- line number of definition of that variable. - PC returned is 0. - FILE:FUNCTION -- likewise, but prefer functions in that file. - *EXPR -- line in which address EXPR appears. - - FUNCTION may be an undebuggable function found in minimal symbol table. - - If the argument FUNFIRSTLINE is nonzero, we want the first line - of real code inside a function when a function is specified. - - DEFAULT_SYMTAB specifies the file to use if none is specified. - It defaults to current_source_symtab. - DEFAULT_LINE specifies the line number to use for relative - line numbers (that start with signs). Defaults to current_source_line. - If CANONICAL is non-NULL, store an array of strings containing the canonical - line specs there if necessary. Currently overloaded member functions and - line numbers or static functions without a filename yield a canonical - line spec. The array and the line spec strings are allocated on the heap, - it is the callers responsibility to free them. - - Note that it is possible to return zero for the symtab - if no file is validly specified. Callers must check that. - Also, the line number returned may be invalid. */ - -/* We allow single quotes in various places. This is a hideous - kludge, which exists because the completer can't yet deal with the - lack of single quotes. FIXME: write a linespec_completer which we - can use as appropriate instead of make_symbol_completion_list. */ - -struct symtabs_and_lines -decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) - char **argptr; - int funfirstline; - struct symtab *default_symtab; - int default_line; - char ***canonical; -{ - struct symtabs_and_lines values; -#ifdef HPPA_COMPILER_BUG - /* FIXME: The native HP 9000/700 compiler has a bug which appears - when optimizing this file with target i960-vxworks. I haven't - been able to construct a simple test case. The problem is that - in the second call to SKIP_PROLOGUE below, the compiler somehow - does not realize that the statement val = find_pc_line (...) will - change the values of the fields of val. It extracts the elements - into registers at the top of the block, and does not update the - registers after the call to find_pc_line. You can check this by - inserting a printf at the end of find_pc_line to show what values - it is returning for val.pc and val.end and another printf after - the call to see what values the function actually got (remember, - this is compiling with cc -O, with this patch removed). You can - also examine the assembly listing: search for the second call to - skip_prologue; the LDO statement before the next call to - find_pc_line loads the address of the structure which - find_pc_line will return; if there is a LDW just before the LDO, - which fetches an element of the structure, then the compiler - still has the bug. - - Setting val to volatile avoids the problem. We must undef - volatile, because the HPPA native compiler does not define - __STDC__, although it does understand volatile, and so volatile - will have been defined away in defs.h. */ -#undef volatile - volatile struct symtab_and_line val; -#define volatile /*nothing*/ -#else - struct symtab_and_line val; -#endif - register char *p, *p1; - char *q, *pp; -#if 0 - char *q1; -#endif - register struct symtab *s; - - register struct symbol *sym; - /* The symtab that SYM was found in. */ - struct symtab *sym_symtab; - - register CORE_ADDR pc; - register struct minimal_symbol *msymbol; - char *copy; - struct symbol *sym_class; - int i1; - int is_quoted, has_parens; - struct symbol **sym_arr; - struct type *t; - char *saved_arg = *argptr; - extern char *gdb_completer_quote_characters; - - /* Defaults have defaults. */ - - if (default_symtab == 0) - { - default_symtab = current_source_symtab; - default_line = current_source_line; - } - - /* See if arg is *PC */ - - if (**argptr == '*') - { - if (**argptr == '*') - { - (*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; - build_canonical_line_spec (values.sals, NULL, canonical); - return values; - } - - /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */ - - s = NULL; - is_quoted = (strchr(gdb_completer_quote_characters, **argptr) != NULL); - has_parens = (( pp = strchr(*argptr, '(')) != NULL && - (pp = strchr(pp, ')')) != NULL); - - for (p = *argptr; *p; p++) - { - if (p[0] == '<') - { - while(++p && *p != '>'); - if (!p) - { - error ("non-matching '<' and '>' in command"); - } - } - if (p[0] == ':' || p[0] == ' ' || p[0] == '\t') - break; - } - while (p[0] == ' ' || p[0] == '\t') p++; - - if ((p[0] == ':') && !has_parens) - { - - /* C++ */ - if (is_quoted) *argptr = *argptr+1; - if (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); - - if (sym_class && - ( TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT - || TYPE_CODE (SYMBOL_TYPE (sym_class)) == 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 (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) - { - char *opname; - char *tmp = alloca (q1 - q + 1); - memcpy (tmp, q, q1 - q); - tmp[q1 - q] = '\0'; - opname = cplus_mangle_opname (tmp, DMGL_ANSI); - if (opname == NULL) - { - error_begin (); - printf_filtered ("no mangling for \"%s\"\n", tmp); - cplusplus_hint (saved_arg); - return_to_top_level (RETURN_ERROR); - } - copy = (char*) alloca (3 + strlen(opname)); - sprintf (copy, "__%s", opname); - p = q1; - } - else -*/ - { - copy = (char *) alloca (p - *argptr + 1 ); - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = '\0'; - if (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 */ - t = SYMBOL_TYPE (sym_class); - sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (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); - } - } - /* end of C++ */ - - - /* Extract the file name. */ - p1 = p; - while (p != *argptr && p[-1] == ' ') --p; - copy = (char *) alloca (p - *argptr + 1); - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = 0; - - /* Find that file's data. */ - s = lookup_symtab (copy); - if (s == 0) - { - if (!have_full_symbols () && !have_partial_symbols ()) - error (no_symtab_msg); - error ("No source file named %s.", copy); - } - - /* Discard the file name from the arg. */ - p = p1 + 1; - while (*p == ' ' || *p == '\t') p++; - *argptr = p; - } - - /* S is specified file's symtab, or 0 if no file specified. - arg no longer contains the file name. */ - - /* Check whether arg is all digits (and sign) */ - - q = *argptr; - if (*q == '-' || *q == '+') q++; - while (*q >= '0' && *q <= '9') - q++; - - if (q != *argptr && (*q == 0 || *q == ' ' || *q == '\t' || *q == ',')) - { - /* We found a token consisting of all digits -- at least one digit. */ - enum sign {none, plus, minus} sign = none; - - /* We might need a canonical line spec if no file was specified. */ - int need_canonical = (s == 0) ? 1 : 0; - - /* This is where we need to make sure that we have good defaults. - We must guarantee that this section of code is never executed - when we are called with just a function name, since - select_source_symtab calls us with such an argument */ - - if (s == 0 && default_symtab == 0) - { - select_source_symtab (0); - default_symtab = current_source_symtab; - default_line = current_source_line; - } - - if (**argptr == '+') - sign = plus, (*argptr)++; - else if (**argptr == '-') - sign = minus, (*argptr)++; - val.line = atoi (*argptr); - switch (sign) - { - case plus: - if (q == *argptr) - val.line = 5; - if (s == 0) - val.line = default_line + val.line; - break; - case minus: - if (q == *argptr) - val.line = 15; - if (s == 0) - val.line = default_line - val.line; - else - val.line = 1; - break; - case none: - break; /* No need to adjust val.line. */ - } - - while (*q == ' ' || *q == '\t') q++; - *argptr = q; - if (s == 0) - s = default_symtab; - val.symtab = s; - val.pc = 0; - values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line)); - values.sals[0] = val; - values.nelts = 1; - if (need_canonical) - build_canonical_line_spec (values.sals, NULL, canonical); - return values; - } - - /* Arg token is not digits => try it as a variable name - Find the next token (everything up to end or next whitespace). */ - - if (is_quoted) - { - p = skip_quoted (*argptr); - if (p[-1] != '\'') - error ("Unmatched single quote."); - } - else if (has_parens) - { - p = pp+1; - } - else - { - p = skip_quoted(*argptr); - } - - copy = (char *) alloca (p - *argptr + 1); - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = '\0'; - if (p != *argptr - && (copy[0] == copy [p - *argptr - 1]) - && strchr (gdb_completer_quote_characters, copy[0]) != NULL) - { - copy [p - *argptr - 1] = '\0'; - copy++; - } - while (*p == ' ' || *p == '\t') p++; - *argptr = p; - - /* Look up that token as a variable. - If file specified, use that file's per-file block to start with. */ - - sym = lookup_symbol (copy, - (s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK) - : get_selected_block ()), - VAR_NAMESPACE, 0, &sym_symtab); - - 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[0] = find_function_start_sal (sym, funfirstline); - values.nelts = 1; - - /* Don't use the SYMBOL_LINE; if used at all it points to - the line containing the parameters or thereabouts, not - the first line of code. */ - - /* We might need a canonical line spec if it is a static - function. */ - if (s == 0) - { - struct blockvector *bv = BLOCKVECTOR (sym_symtab); - struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - if (lookup_block_symbol (b, copy, VAR_NAMESPACE) != NULL) - build_canonical_line_spec (values.sals, copy, canonical); - } - return values; - } - else if (SYMBOL_LINE (sym) != 0) - { - /* We know its line number. */ - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - values.nelts = 1; - memset (&values.sals[0], 0, sizeof (values.sals[0])); - values.sals[0].symtab = sym_symtab; - values.sals[0].line = SYMBOL_LINE (sym); - return values; - } - else - /* This can happen if it is compiled with a compiler which doesn't - put out line numbers for variables. */ - /* FIXME: Shouldn't we just set .line and .symtab to zero and - return? For example, "info line foo" could print the address. */ - error ("Line number not known for symbol \"%s\"", copy); - } - - msymbol = lookup_minimal_symbol (copy, (struct objfile *) NULL); - if (msymbol != NULL) - { - val.symtab = 0; - val.line = 0; - val.pc = SYMBOL_VALUE_ADDRESS (msymbol); - if (funfirstline) - { - val.pc += FUNCTION_START_OFFSET; - SKIP_PROLOGUE (val.pc); - } - values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line)); - values.sals[0] = val; - values.nelts = 1; - return values; - } - - if (!have_full_symbols () && - !have_partial_symbols () && !have_minimal_symbols ()) - error (no_symtab_msg); - - error ("Function \"%s\" not defined.", copy); - return values; /* for lint */ -} - -struct symtabs_and_lines -decode_line_spec (string, funfirstline) - char *string; - int funfirstline; -{ - struct symtabs_and_lines sals; - if (string == 0) - error ("Empty line specification."); - sals = decode_line_1 (&string, funfirstline, - current_source_symtab, current_source_line, - (char ***)NULL); - if (*string) - error ("Junk at end of line specification: %s", string); - return sals; -} - -/* Given a list of NELTS symbols in SYM_ARR, return a list of lines to - operate on (ask user if necessary). - If CANONICAL is non-NULL return a corresponding array of mangled names - as canonical line specs there. */ - -static struct symtabs_and_lines -decode_line_2 (sym_arr, nelts, funfirstline, canonical) - struct symbol *sym_arr[]; - int nelts; - int funfirstline; - char ***canonical; -{ - struct symtabs_and_lines values, return_values; - char *args, *arg1; - int i; - char *prompt; - char *symname; - 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)); - old_chain = make_cleanup (free, return_values.sals); - - if (canonical) - { - canonical_arr = (char **) xmalloc (nelts * sizeof (char *)); - make_cleanup (free, canonical_arr); - memset (canonical_arr, 0, nelts * sizeof (char *)); - *canonical = canonical_arr; - } - - i = 0; - printf_unfiltered("[0] cancel\n[1] all\n"); - while (i < nelts) - { - if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK) - { - values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline); - printf_unfiltered ("[%d] %s at %s:%d\n", - (i+2), - SYMBOL_SOURCE_NAME (sym_arr[i]), - values.sals[i].symtab->filename, - values.sals[i].line); - } - else - printf_unfiltered ("?HERE\n"); - i++; - } - - if ((prompt = getenv ("PS2")) == NULL) - { - prompt = ">"; - } - printf_unfiltered("%s ",prompt); - gdb_flush(gdb_stdout); - - args = command_line_input ((char *) NULL, 0, "overload-choice"); - - if (args == 0 || *args == 0) - error_no_arg ("one or more choice numbers"); - - i = 0; - while (*args) - { - int num; - - arg1 = args; - while (*arg1 >= '0' && *arg1 <= '9') arg1++; - if (*arg1 && *arg1 != ' ' && *arg1 != '\t') - error ("Arguments must be choice numbers."); - - num = atoi (args); - - if (num == 0) - error ("cancelled"); - else if (num == 1) - { - if (canonical_arr) - { - for (i = 0; i < nelts; i++) - { - if (canonical_arr[i] == NULL) - { - symname = SYMBOL_NAME (sym_arr[i]); - canonical_arr[i] = savestring (symname, strlen (symname)); - } - } - } - memcpy (return_values.sals, values.sals, - (nelts * sizeof(struct symtab_and_line))); - return_values.nelts = nelts; - discard_cleanups (old_chain); - return return_values; - } - - if (num > nelts + 2) - { - printf_unfiltered ("No choice number %d.\n", num); - } - else - { - num -= 2; - if (values.sals[num].pc) - { - if (canonical_arr) - { - symname = SYMBOL_NAME (sym_arr[num]); - make_cleanup (free, symname); - canonical_arr[i] = savestring (symname, strlen (symname)); - } - return_values.sals[i++] = values.sals[num]; - values.sals[num].pc = 0; - } - else - { - printf_unfiltered ("duplicate request for %d ignored.\n", num); - } - } - - args = arg1; - while (*args == ' ' || *args == '\t') args++; - } - return_values.nelts = i; - discard_cleanups (old_chain); - return return_values; -} - - -/* Slave routine for sources_info. Force line breaks at ,'s. - NAME is the name to print and *FIRST is nonzero if this is the first - name printed. Set *FIRST to zero. */ -static void -output_source_filename (name, first) - char *name; - int *first; -{ - /* Table of files printed so far. Since a single source file can - result in several partial symbol tables, we need to avoid printing - it more than once. Note: if some of the psymtabs are read in and - some are not, it gets printed both under "Source files for which - symbols have been read" and "Source files for which symbols will - be read in on demand". I consider this a reasonable way to deal - with the situation. I'm not sure whether this can also happen for - symtabs; it doesn't hurt to check. */ - static char **tab = NULL; - /* Allocated size of tab in elements. - Start with one 256-byte block (when using GNU malloc.c). - 24 is the malloc overhead when range checking is in effect. */ - static int tab_alloc_size = (256 - 24) / sizeof (char *); - /* Current size of tab in elements. */ - static int tab_cur_size; - - char **p; - - if (*first) - { - if (tab == NULL) - tab = (char **) xmalloc (tab_alloc_size * sizeof (*tab)); - tab_cur_size = 0; - } - - /* Is NAME in tab? */ - for (p = tab; p < tab + tab_cur_size; p++) - if (STREQ (*p, name)) - /* Yes; don't print it again. */ - return; - /* No; add it to tab. */ - if (tab_cur_size == tab_alloc_size) - { - tab_alloc_size *= 2; - tab = (char **) xrealloc ((char *) tab, tab_alloc_size * sizeof (*tab)); - } - tab[tab_cur_size++] = name; - - if (*first) - { - *first = 0; - } - else - { - printf_filtered (", "); - } - - wrap_here (""); - fputs_filtered (name, gdb_stdout); -} - -static void -sources_info (ignore, from_tty) - char *ignore; - int from_tty; -{ - register struct symtab *s; - register struct partial_symtab *ps; - register struct objfile *objfile; - int first; - - if (!have_full_symbols () && !have_partial_symbols ()) - { - error (no_symtab_msg); - } - - printf_filtered ("Source files for which symbols have been read in:\n\n"); - - first = 1; - ALL_SYMTABS (objfile, s) - { - output_source_filename (s -> filename, &first); - } - printf_filtered ("\n\n"); - - printf_filtered ("Source files for which symbols will be read in on demand:\n\n"); - - first = 1; - ALL_PSYMTABS (objfile, ps) - { - if (!ps->readin) - { - output_source_filename (ps -> filename, &first); - } - } - 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. - - BPT is non-zero if we should set a breakpoint at the functions - we find. */ - -static void -list_symbols (regexp, class, bpt, from_tty) - char *regexp; - int class; - int bpt; - int from_tty; -{ - 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 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}; - static enum minimal_symbol_type types2[] - = {mst_bss, mst_file_text, mst_abs, mst_unknown}; - static enum minimal_symbol_type types3[] - = {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]; - - 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 or . */ - 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 (0 != (val = re_comp (regexp))) - error ("Invalid regexp (%s): %s", val, regexp); - } - - /* Search through the partial symtabs *first* for all symbols - matching the regexp. That way we don't have to reproduce all of - the machinery below. */ - - ALL_PSYMTABS (objfile, ps) - { - 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. */ - 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++; - } - } - - /* Here, we search through the minimal symbol tables for functions that - match, and call find_pc_symtab on them to force their symbols to - be read. The symbol will then be found during the scan of symtabs - below. If find_pc_symtab fails, set found_misc so that we will - rescan to print any matching symbols without debug info. */ - - if (class == 1) - { - 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))) - { - 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. */ - 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 - } - } - } - } - 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) - { - 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 (!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)); - } - } - } - } - } - } -} - -static void -variables_info (regexp, from_tty) - char *regexp; - int from_tty; -{ - list_symbols (regexp, 0, 0, from_tty); -} - -static void -functions_info (regexp, from_tty) - char *regexp; - int from_tty; -{ - list_symbols (regexp, 1, 0, from_tty); -} - -static void -types_info (regexp, from_tty) - char *regexp; - int from_tty; -{ - list_symbols (regexp, 2, 0, from_tty); -} - -#if 0 -/* Tiemann says: "info methods was never implemented." */ -static void -methods_info (regexp) - char *regexp; -{ - list_symbols (regexp, 3, 0, from_tty); -} -#endif /* 0 */ - -/* Breakpoint all functions matching regular expression. */ -static void -rbreak_command (regexp, from_tty) - char *regexp; - int from_tty; -{ - list_symbols (regexp, 1, 1, from_tty); -} - - -/* Return Nonzero if block a is lexically nested within block b, - or if a and b have the same pc range. - Return zero otherwise. */ -int -contained_in (a, b) - struct block *a, *b; -{ - if (!a || !b) - return 0; - return BLOCK_START (a) >= BLOCK_START (b) - && BLOCK_END (a) <= BLOCK_END (b); -} - - -/* Helper routine for make_symbol_completion_list. */ - -static int return_val_size; -static int return_val_index; -static char **return_val; - -#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \ - do { \ - if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \ - /* Put only the mangled name on the list. */ \ - /* Advantage: "b foo" completes to "b foo(int, int)" */ \ - /* Disadvantage: "b foo__i" doesn't complete. */ \ - completion_list_add_name \ - (SYMBOL_DEMANGLED_NAME (symbol), (sym_text), (len), (text), (word)); \ - else \ - completion_list_add_name \ - (SYMBOL_NAME (symbol), (sym_text), (len), (text), (word)); \ - } while (0) - -/* 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 -completion_list_add_name (symname, sym_text, sym_text_len, text, word) - char *symname; - char *sym_text; - int sym_text_len; - char *text; - char *word; -{ - int newsize; - int i; - - /* clip symbols that cannot match */ - - if (strncmp (symname, sym_text, sym_text_len) != 0) - { - return; - } - - /* Clip any symbol names that we've already considered. (This is a - time optimization) */ - - for (i = 0; i < return_val_index; ++i) - { - if (STREQ (symname, return_val[i])) - { - return; - } - } - - /* We have a match for a completion, so add SYMNAME to the current list - of matches. Note that the name is moved to freshly malloc'd space. */ - - { - char *new; - if (word == sym_text) - { - new = xmalloc (strlen (symname) + 5); - strcpy (new, symname); - } - else if (word > sym_text) - { - /* Return some portion of symname. */ - new = xmalloc (strlen (symname) + 5); - strcpy (new, symname + (word - sym_text)); - } - else - { - /* Return some of SYM_TEXT plus symname. */ - new = xmalloc (strlen (symname) + (sym_text - word) + 5); - strncpy (new, word, sym_text - word); - new[sym_text - word] = '\0'; - strcat (new, symname); - } - - if (return_val_index + 3 > return_val_size) - { - newsize = (return_val_size *= 2) * sizeof (char *); - return_val = (char **) xrealloc ((char *) return_val, newsize); - } - return_val[return_val_index++] = new; - return_val[return_val_index] = NULL; - } -} - -/* Return a NULL terminated array of all symbols (regardless of class) which - begin by matching TEXT. If the answer is no symbols, then the return value - is an array which contains only a NULL pointer. - - Problem: All of the symbols have to be copied because readline frees them. - I'm not going to worry about this; hopefully there won't be that many. */ - -char ** -make_symbol_completion_list (text, word) - char *text; - char *word; -{ - 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 symbol we are completing on. Points in same buffer as text. */ - char *sym_text; - /* Length of sym_text. */ - int sym_text_len; - - /* Now look for the symbol we are supposed to complete on. - FIXME: This should be language-specific. */ - { - char *p; - char quote_found; - char *quote_pos = NULL; - - /* First see if this is a quoted string. */ - quote_found = '\0'; - for (p = text; *p != '\0'; ++p) - { - if (quote_found != '\0') - { - if (*p == quote_found) - /* Found close quote. */ - quote_found = '\0'; - else if (*p == '\\' && p[1] == quote_found) - /* A backslash followed by the quote character - doesn't end the string. */ - ++p; - } - else if (*p == '\'' || *p == '"') - { - quote_found = *p; - quote_pos = p; - } - } - if (quote_found == '\'') - /* A string within single quotes can be a symbol, so complete on it. */ - sym_text = quote_pos + 1; - else if (quote_found == '"') - /* A double-quoted string is never a symbol, nor does it make sense - to complete it any other way. */ - return NULL; - else - { - /* It is not a quoted string. Break it based on the characters - which are in symbols. */ - while (p > text) - { - if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0') - --p; - else - break; - } - sym_text = p; - } - } - - sym_text_len = strlen (sym_text); - - return_val_size = 100; - return_val_index = 0; - return_val = (char **) xmalloc ((return_val_size + 1) * sizeof (char *)); - return_val[0] = NULL; - - /* Look through the partial symtabs for all symbols which begin - by matching SYM_TEXT. 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; - COMPLETION_LIST_ADD_SYMBOL (psym, sym_text, sym_text_len, text, word); - } - - for (psym = objfile->static_psymbols.list + ps->statics_offset; - psym < (objfile->static_psymbols.list + ps->statics_offset - + ps->n_static_syms); - psym++) - { - QUIT; - COMPLETION_LIST_ADD_SYMBOL (psym, sym_text, sym_text_len, text, word); - } - } - - /* 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; - COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word); - } - - /* 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 elmin 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); - COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); - if (SYMBOL_CLASS (sym) == LOC_TYPEDEF) - { - struct type *t = SYMBOL_TYPE (sym); - enum type_code c = TYPE_CODE (t); - - if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT) - { - for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++) - { - if (TYPE_FIELD_NAME (t, j)) - { - completion_list_add_name (TYPE_FIELD_NAME (t, j), - sym_text, sym_text_len, text, word); - } - } - } - } - } - } - - /* 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); - COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); - } - } - - 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); - COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); - } - } - - return (return_val); -} - - -#if 0 -/* Add the type of the symbol sym to the type of the current - function whose block we are in (assumed). The type of - this current function is contained in *TYPE. - - This basically works as follows: When we find a function - symbol (N_FUNC with a 'f' or 'F' in the symbol name), we record - a pointer to its type in the global in_function_type. Every - time we come across a parameter symbol ('p' in its name), then - this procedure adds the name and type of that parameter - to the function type pointed to by *TYPE. (Which should correspond - to in_function_type if it was called correctly). - - Note that since we are modifying a type, the result of - lookup_function_type() should be memcpy()ed before calling - this. When not in strict typing mode, the expression - evaluator can choose to ignore this. - - Assumption: All of a function's parameter symbols will - appear before another function symbol is found. The parameters - appear in the same order in the argument list as they do in the - symbol table. */ - -void -add_param_to_type (type,sym) - struct type **type; - struct symbol *sym; -{ - int num = ++(TYPE_NFIELDS(*type)); - - if(TYPE_NFIELDS(*type)-1) - TYPE_FIELDS(*type) = (struct field *) - (*current_objfile->xrealloc) ((char *)(TYPE_FIELDS(*type)), - num*sizeof(struct field)); - else - TYPE_FIELDS(*type) = (struct field *) - (*current_objfile->xmalloc) (num*sizeof(struct field)); - - TYPE_FIELD_BITPOS(*type,num-1) = num-1; - TYPE_FIELD_BITSIZE(*type,num-1) = 0; - TYPE_FIELD_TYPE(*type,num-1) = SYMBOL_TYPE(sym); - TYPE_FIELD_NAME(*type,num-1) = SYMBOL_NAME(sym); -} -#endif - -void -_initialize_symtab () -{ - add_info ("variables", variables_info, - "All global and static variable names, or those matching REGEXP."); - add_info ("functions", functions_info, - "All function names, or those matching REGEXP."); - - /* FIXME: This command has at least the following problems: - 1. It prints builtin types (in a very strange and confusing fashion). - 2. It doesn't print right, e.g. with - typedef struct foo *FOO - type_print prints "FOO" when we want to make it (in this situation) - print "struct foo *". - I also think "ptype" or "whatis" is more likely to be useful (but if - there is much disagreement "info types" can be fixed). */ - add_info ("types", types_info, - "All type names, or those matching REGEXP."); - -#if 0 - add_info ("methods", methods_info, - "All method names, or those matching REGEXP::REGEXP.\n\ -If the class qualifier is omitted, it is assumed to be the current scope.\n\ -If the first REGEXP is omitted, then all methods matching the second REGEXP\n\ -are listed."); -#endif - add_info ("sources", sources_info, - "Source files in the program."); - - add_com ("rbreak", no_class, rbreak_command, - "Set a breakpoint for all functions matching REGEXP."); - - /* Initialize the one built-in type that isn't language dependent... */ - builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0, - "", (struct objfile *) NULL); -} diff --git a/gnu/usr.bin/gdb/gdb/symtab.h b/gnu/usr.bin/gdb/gdb/symtab.h deleted file mode 100644 index 5e4fa56..0000000 --- a/gnu/usr.bin/gdb/gdb/symtab.h +++ /dev/null @@ -1,1176 +0,0 @@ -/* Symbol table definitions for GDB. - Copyright 1986, 1989, 1991, 1992, 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. */ - -#if !defined (SYMTAB_H) -#define SYMTAB_H 1 - -/* Some definitions and declarations to go with use of obstacks. */ - -#include "obstack.h" -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* Don't do this; it means that if some .o's are compiled with GNU C - and some are not (easy to do accidentally the way we configure - things; also it is a pain to have to "make clean" every time you - want to switch compilers), then GDB dies a horrible death. */ -/* GNU C supports enums that are bitfields. Some compilers don't. */ -#if 0 && defined(__GNUC__) && !defined(BYTE_BITFIELD) -#define BYTE_BITFIELD :8; -#else -#define BYTE_BITFIELD /*nothing*/ -#endif - -/* Define a structure for the information that is common to all symbol types, - including minimal symbols, partial symbols, and full symbols. In a - multilanguage environment, some language specific information may need to - be recorded along with each symbol. - - These fields are ordered to encourage good packing, since we frequently - have tens or hundreds of thousands of these. */ - -struct general_symbol_info -{ - /* Name of the symbol. This is a required field. Storage for the name is - allocated on the psymbol_obstack or symbol_obstack for the associated - objfile. */ - - char *name; - - /* Value of the symbol. Which member of this union to use, and what - it means, depends on what kind of symbol this is and its - SYMBOL_CLASS. See comments there for more details. All of these - are in host byte order (though what they point to might be in - target byte order, e.g. LOC_CONST_BYTES). */ - - union - { - /* The fact that this is a long not a LONGEST mainly limits the - range of a LOC_CONST. Since LOC_CONST_BYTES exists, I'm not - sure that is a big deal. */ - long ivalue; - - struct block *block; - - char *bytes; - - CORE_ADDR address; - - /* for opaque typedef struct chain */ - - struct symbol *chain; - } - value; - - /* Since one and only one language can apply, wrap the language specific - information inside a union. */ - - union - { - struct cplus_specific /* For C++ */ - { - char *demangled_name; - } cplus_specific; - struct chill_specific /* For Chill */ - { - char *demangled_name; - } chill_specific; - } language_specific; - - /* Record the source code language that applies to this symbol. - This is used to select one of the fields from the language specific - union above. */ - - enum language language BYTE_BITFIELD; - - /* Which section is this symbol in? This is an index into - section_offsets for this objfile. Negative means that the symbol - does not get relocated relative to a section. - Disclaimer: currently this is just used for xcoff, so don't - expect all symbol-reading code to set it correctly (the ELF code - also tries to set it correctly). */ - - short section; -}; - -#define SYMBOL_NAME(symbol) (symbol)->ginfo.name -#define SYMBOL_VALUE(symbol) (symbol)->ginfo.value.ivalue -#define SYMBOL_VALUE_ADDRESS(symbol) (symbol)->ginfo.value.address -#define SYMBOL_VALUE_BYTES(symbol) (symbol)->ginfo.value.bytes -#define SYMBOL_BLOCK_VALUE(symbol) (symbol)->ginfo.value.block -#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_CPLUS_DEMANGLED_NAME(symbol) \ - (symbol)->ginfo.language_specific.cplus_specific.demangled_name - -/* Macro that initializes the language dependent portion of a symbol - depending upon the language for the symbol. */ - -#define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \ - do { \ - SYMBOL_LANGUAGE (symbol) = language; \ - if (SYMBOL_LANGUAGE (symbol) == language_cplus) \ - { \ - SYMBOL_CPLUS_DEMANGLED_NAME (symbol) = NULL; \ - } \ - else if (SYMBOL_LANGUAGE (symbol) == language_chill) \ - { \ - SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; \ - } \ - else \ - { \ - memset (&(symbol)->ginfo.language_specific, 0, \ - sizeof ((symbol)->ginfo.language_specific)); \ - } \ - } while (0) - -/* Macro that attempts to initialize the demangled name for a symbol, - based on the language of that symbol. If the language is set to - language_auto, it will attempt to find any demangling algorithm - that works and then set the language appropriately. If no demangling - of any kind is found, the language is set back to language_unknown, - so we can avoid doing this work again the next time we encounter - the symbol. Any required space to store the name is obtained from the - specified obstack. */ - -#define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack) \ - do { \ - char *demangled = NULL; \ - if (SYMBOL_LANGUAGE (symbol) == language_cplus \ - || SYMBOL_LANGUAGE (symbol) == language_auto) \ - { \ - demangled = \ - cplus_demangle (SYMBOL_NAME (symbol), DMGL_PARAMS | DMGL_ANSI);\ - if (demangled != NULL) \ - { \ - SYMBOL_LANGUAGE (symbol) = language_cplus; \ - 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)) \ - { \ - demangled = \ - chill_demangle (SYMBOL_NAME (symbol)); \ - if (demangled != NULL) \ - { \ - SYMBOL_LANGUAGE (symbol) = language_chill; \ - SYMBOL_CHILL_DEMANGLED_NAME (symbol) = \ - obsavestring (demangled, strlen (demangled), (obstack)); \ - free (demangled); \ - } \ - else \ - { \ - SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; \ - } \ - } \ - if (SYMBOL_LANGUAGE (symbol) == language_auto) \ - { \ - SYMBOL_LANGUAGE (symbol) = language_unknown; \ - } \ - } while (0) - -/* Macro that returns the demangled name for a symbol based on the language - for that symbol. If no demangled name exists, returns NULL. */ - -#define SYMBOL_DEMANGLED_NAME(symbol) \ - (SYMBOL_LANGUAGE (symbol) == language_cplus \ - ? SYMBOL_CPLUS_DEMANGLED_NAME (symbol) \ - : (SYMBOL_LANGUAGE (symbol) == language_chill \ - ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) \ - : NULL)) - -#define SYMBOL_CHILL_DEMANGLED_NAME(symbol) \ - (symbol)->ginfo.language_specific.chill_specific.demangled_name - -/* Macro that returns the "natural source name" of a symbol. In C++ this is - the "demangled" form of the name if demangle is on and the "mangled" form - of the name if demangle is off. In other languages this is just the - symbol name. The result should never be NULL. */ - -#define SYMBOL_SOURCE_NAME(symbol) \ - (demangle && SYMBOL_DEMANGLED_NAME (symbol) != NULL \ - ? SYMBOL_DEMANGLED_NAME (symbol) \ - : SYMBOL_NAME (symbol)) - -/* Macro that returns the "natural assembly name" of a symbol. In C++ this is - the "mangled" form of the name if demangle is off, or if demangle is on and - asm_demangle is off. Otherwise if asm_demangle is on it is the "demangled" - form. In other languages this is just the symbol name. The result should - never be NULL. */ - -#define SYMBOL_LINKAGE_NAME(symbol) \ - (demangle && asm_demangle && SYMBOL_DEMANGLED_NAME (symbol) != NULL \ - ? SYMBOL_DEMANGLED_NAME (symbol) \ - : SYMBOL_NAME (symbol)) - -/* Macro that tests a symbol for a match against a specified name string. - First test the unencoded name, then looks for and test a C++ encoded - name if it exists. Note that whitespace is ignored while attempting to - match a C++ encoded name, so that "foo::bar(int,long)" is the same as - "foo :: bar (int, long)". - Evaluates to zero if the match fails, or nonzero if it succeeds. */ - -#define SYMBOL_MATCHES_NAME(symbol, name) \ - (STREQ (SYMBOL_NAME (symbol), (name)) \ - || (SYMBOL_DEMANGLED_NAME (symbol) != NULL \ - && strcmp_iw (SYMBOL_DEMANGLED_NAME (symbol), (name)) == 0)) - -/* Macro that tests a symbol for an re-match against the last compiled regular - expression. First test the unencoded name, then look for and test a C++ - encoded name if it exists. - Evaluates to zero if the match fails, or nonzero if it succeeds. */ - -#define SYMBOL_MATCHES_REGEXP(symbol) \ - (re_exec (SYMBOL_NAME (symbol)) != 0 \ - || (SYMBOL_DEMANGLED_NAME (symbol) != NULL \ - && re_exec (SYMBOL_DEMANGLED_NAME (symbol)) != 0)) - -/* Define a simple structure used to hold some very basic information about - all defined global symbols (text, data, bss, abs, etc). The only required - information is the general_symbol_info. - - In many cases, even if a file was compiled with no special options for - debugging at all, as long as was not stripped it will contain sufficient - information to build a useful minimal symbol table using this structure. - Even when a file contains enough debugging information to build a full - symbol table, these minimal symbols are still useful for quickly mapping - between names and addresses, and vice versa. They are also sometimes - used to figure out what full symbol table entries need to be read in. */ - -struct minimal_symbol -{ - - /* The general symbol info required for all types of symbols. - - The SYMBOL_VALUE_ADDRESS contains the address that this symbol - corresponds to. */ - - 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. */ - - char *info; - - /* Classification types for this symbol. These should be taken as "advisory - only", since if gdb can't easily figure out a classification it simply - selects mst_unknown. It may also have to guess when it can't figure out - which is a better match between two types (mst_data versus mst_bss) for - example. Since the minimal symbol info is sometimes derived from the - BFD library's view of a file, we need to live with what information bfd - supplies. */ - - enum minimal_symbol_type - { - mst_unknown = 0, /* Unknown type, the default */ - mst_text, /* Generally executable instructions */ - mst_data, /* Generally initialized data */ - mst_bss, /* Generally uninitialized data */ - mst_abs, /* Generally absolute (nonrelocatable) */ - /* GDB uses mst_solib_trampoline for the start address of a shared - library trampoline entry. Breakpoints for shared library functions - are put there if the shared library is not yet loaded. - After the shared library is loaded, lookup_minimal_symbol will - prefer the minimal symbol from the shared library (usually - a mst_text symbol) over the mst_solib_trampoline symbol, and the - breakpoints will be moved to their true address in the shared - library via breakpoint_re_set. */ - mst_solib_trampoline, /* Shared library trampoline code */ - /* For the mst_file* types, the names are only guaranteed to be unique - within a given .o file. */ - mst_file_text, /* Static version of mst_text */ - 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 -#define MSYMBOL_TYPE(msymbol) (msymbol)->type - - -/* All of the name-scope contours of the program - are represented by `struct block' objects. - All of these objects are pointed to by the blockvector. - - Each block represents one name scope. - Each lexical context has its own block. - - The blockvector begins with some special blocks. - The GLOBAL_BLOCK contains all the symbols defined in this compilation - whose scope is the entire program linked together. - The STATIC_BLOCK contains all the symbols whose scope is the - entire compilation excluding other separate compilations. - Blocks starting with the FIRST_LOCAL_BLOCK are not special. - - Each block records a range of core addresses for the code that - is in the scope of the block. The STATIC_BLOCK and GLOBAL_BLOCK - give, for the range of code, the entire range of code produced - by the compilation that the symbol segment belongs to. - - The blocks appear in the blockvector - in order of increasing starting-address, - and, within that, in order of decreasing ending-address. - - This implies that within the body of one function - the blocks appear in the order of a depth-first tree walk. */ - -struct blockvector -{ - /* Number of blocks in the list. */ - int nblocks; - /* The blocks themselves. */ - struct block *block[1]; -}; - -#define BLOCKVECTOR_NBLOCKS(blocklist) (blocklist)->nblocks -#define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n] - -/* Special block numbers */ - -#define GLOBAL_BLOCK 0 -#define STATIC_BLOCK 1 -#define FIRST_LOCAL_BLOCK 2 - -struct block -{ - - /* Addresses in the executable code that are in this block. */ - - CORE_ADDR startaddr; - CORE_ADDR endaddr; - - /* The symbol that names this block, if the block is the body of a - function; otherwise, zero. */ - - struct symbol *function; - - /* The `struct block' for the containing block, or 0 if none. - - The superblock of a top-level local block (i.e. a function in the - case of C) is the STATIC_BLOCK. The superblock of the - STATIC_BLOCK is the GLOBAL_BLOCK. */ - - struct block *superblock; - - /* Version of GCC used to compile the function corresponding - to this block, or 0 if not compiled with GCC. When possible, - GCC should be compatible with the native compiler, or if that - is not feasible, the differences should be fixed during symbol - reading. As of 16 Apr 93, this flag is never used to distinguish - between gcc2 and the native compiler. - - If there is no function corresponding to this block, this meaning - of this flag is undefined. */ - - unsigned char gcc_compile_flag; - - /* Number of local symbols. */ - - int nsyms; - - /* The symbols. If some of them are arguments, then they must be - in the order in which we would like to print them. */ - - struct symbol *sym[1]; -}; - -#define BLOCK_START(bl) (bl)->startaddr -#define BLOCK_END(bl) (bl)->endaddr -#define BLOCK_NSYMS(bl) (bl)->nsyms -#define BLOCK_SYM(bl, n) (bl)->sym[n] -#define BLOCK_FUNCTION(bl) (bl)->function -#define BLOCK_SUPERBLOCK(bl) (bl)->superblock -#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag - -/* Nonzero if symbols of block BL should be sorted alphabetically. - Don't sort a block which corresponds to a function. If we did the - sorting would have to preserve the order of the symbols for the - arguments. */ - -#define BLOCK_SHOULD_SORT(bl) ((bl)->nsyms >= 40 && BLOCK_FUNCTION (bl) == NULL) - - -/* Represent one symbol name; a variable, constant, function or typedef. */ - -/* Different name spaces for symbols. Looking up a symbol specifies a - namespace and ignores symbol definitions in other name spaces. */ - -enum namespace -{ - /* UNDEF_NAMESPACE is used when a namespace has not been discovered or - none of the following apply. This usually indicates an error either - in the symbol information or in gdb's handling of symbols. */ - - UNDEF_NAMESPACE, - - /* VAR_NAMESPACE is the usual namespace. In C, this contains variables, - function names, typedef names and enum type values. */ - - VAR_NAMESPACE, - - /* STRUCT_NAMESPACE is used in C to hold struct, union and enum type names. - Thus, if `struct foo' is used in a C program, it produces a symbol named - `foo' in the STRUCT_NAMESPACE. */ - - STRUCT_NAMESPACE, - - /* 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 -}; - -/* An address-class says where to find the value of a symbol. */ - -enum address_class -{ - /* Not used; catches errors */ - - LOC_UNDEF, - - /* Value is constant int SYMBOL_VALUE, host byteorder */ - - LOC_CONST, - - /* Value is at fixed address SYMBOL_VALUE_ADDRESS */ - - LOC_STATIC, - - /* Value is in register. SYMBOL_VALUE is the register number. */ - - LOC_REGISTER, - - /* It's an argument; the value is at SYMBOL_VALUE offset in arglist. */ - - LOC_ARG, - - /* Value address is at SYMBOL_VALUE offset in arglist. */ - - LOC_REF_ARG, - - /* Value is in register number SYMBOL_VALUE. Just like LOC_REGISTER - except this is an argument. Probably the cleaner way to handle - this would be to separate address_class (which would include - separate ARG and LOCAL to deal with FRAME_ARGS_ADDRESS versus - FRAME_LOCALS_ADDRESS), and an is_argument flag. - - For some symbol formats (stabs, for some compilers at least), - the compiler generates two symbols, an argument and a register. - In some cases we combine them to a single LOC_REGPARM in symbol - reading, but currently not for all cases (e.g. it's passed on the - stack and then loaded into a register). */ - - LOC_REGPARM, - - /* Value is in specified register. Just like LOC_REGPARM except the - register holds the address of the argument instead of the argument - itself. This is currently used for the passing of structs and unions - on sparc and hppa. It is also used for call by reference where the - address is in a register, at least by mipsread.c. */ - - LOC_REGPARM_ADDR, - - /* Value is a local variable at SYMBOL_VALUE offset in stack frame. */ - - LOC_LOCAL, - - /* Value not used; definition in SYMBOL_TYPE. Symbols in the namespace - STRUCT_NAMESPACE all have this class. */ - - LOC_TYPEDEF, - - /* Value is address SYMBOL_VALUE_ADDRESS in the code */ - - LOC_LABEL, - - /* In a symbol table, value is SYMBOL_BLOCK_VALUE of a `struct block'. - In a partial symbol table, SYMBOL_VALUE_ADDRESS is the start address - of the block. Function names have this class. */ - - LOC_BLOCK, - - /* Value is a constant byte-sequence pointed to by SYMBOL_VALUE_BYTES, in - target byte order. */ - - LOC_CONST_BYTES, - - /* Value is arg at SYMBOL_VALUE offset in stack frame. Differs from - LOC_LOCAL in that symbol is an argument; differs from LOC_ARG in - that we find it in the frame (FRAME_LOCALS_ADDRESS), not in the - arglist (FRAME_ARGS_ADDRESS). Added for i960, which passes args - in regs then copies to frame. */ - - LOC_LOCAL_ARG, - - /* Value is at SYMBOL_VALUE offset from the current value of - register number SYMBOL_BASEREG. This exists mainly for the same - things that LOC_LOCAL and LOC_ARG do; but we need to do this - instead because on 88k DWARF gives us the offset from the - frame/stack pointer, rather than the offset from the "canonical - frame address" used by COFF, stabs, etc., and we don't know how - to convert between these until we start examining prologues. - - Note that LOC_BASEREG is much less general than a DWARF expression. - We don't need the generality (at least not yet), and storing a general - DWARF expression would presumably take up more space than the existing - scheme. */ - - LOC_BASEREG, - - /* Same as LOC_BASEREG but it is an argument. */ - - LOC_BASEREG_ARG, - - /* The variable does not actually exist in the program. - The value is ignored. */ - - LOC_OPTIMIZED_OUT -}; - -struct symbol -{ - - /* The general symbol info required for all types of symbols. */ - - struct general_symbol_info ginfo; - - /* Data type of value */ - - struct type *type; - - /* Name space code. */ - - enum namespace namespace BYTE_BITFIELD; - - /* Address class */ - - enum address_class class BYTE_BITFIELD; - - /* Line number of definition. FIXME: Should we really make the assumption - that nobody will try to debug files longer than 64K lines? What about - machine generated programs? */ - - unsigned short line; - - /* Some symbols require an additional value to be recorded on a per- - symbol basis. Stash those values here. */ - - union - { - /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */ - short basereg; - } - aux_value; -}; - -#define SYMBOL_NAMESPACE(symbol) (symbol)->namespace -#define SYMBOL_CLASS(symbol) (symbol)->class -#define SYMBOL_TYPE(symbol) (symbol)->type -#define SYMBOL_LINE(symbol) (symbol)->line -#define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg - -/* A partial_symbol records the name, namespace, and address class of - symbols whose types we have not parsed yet. For functions, it also - contains their memory address, so we can find them from a PC value. - Each partial_symbol sits in a partial_symtab, all of which are chained - on a partial symtab list and which points to the corresponding - normal symtab once the partial_symtab has been referenced. */ - -struct partial_symbol -{ - - /* The general symbol info required for all types of symbols. */ - - struct general_symbol_info ginfo; - - /* Name space code. */ - - enum namespace namespace BYTE_BITFIELD; - - /* Address class (for info_symbols) */ - - enum address_class class BYTE_BITFIELD; - -}; - -#define PSYMBOL_NAMESPACE(psymbol) (psymbol)->namespace -#define PSYMBOL_CLASS(psymbol) (psymbol)->class - - -/* Source-file information. This describes the relation between source files, - ine numbers and addresses in the program text. */ - -struct sourcevector -{ - int length; /* Number of source files described */ - struct source *source[1]; /* Descriptions of the files */ -}; - -/* Each item represents a line-->pc (or the reverse) mapping. This is - somewhat more wasteful of space than one might wish, but since only - the files which are actually debugged are read in to core, we don't - waste much space. */ - -struct linetable_entry -{ - int line; - CORE_ADDR pc; -}; - -/* The order of entries in the linetable is significant. They should - be sorted by increasing values of the pc field. If there is more than - one entry for a given pc, then I'm not sure what should happen (and - I not sure whether we currently handle it the best way). - - Example: a C for statement generally looks like this - - 10 0x100 - for the init/test part of a for stmt. - 20 0x200 - 30 0x300 - 10 0x400 - for the increment part of a for stmt. - - */ - -struct linetable -{ - int nitems; - - /* Actually NITEMS elements. If you don't like this use of the - `struct hack', you can shove it up your ANSI (seriously, if the - committee tells us how to do it, we can probably go along). */ - struct linetable_entry item[1]; -}; - -/* All the information on one source file. */ - -struct source -{ - char *name; /* Name of file */ - struct linetable contents; -}; - -/* How to relocate the symbols from each section in a symbol file. - Each struct contains an array of offsets. - The ordering and meaning of the offsets is file-type-dependent; - typically it is indexed by section numbers or symbol types or - something like that. - - To give us flexibility in changing the internal representation - of these offsets, the ANOFFSET macro must be used to insert and - extract offset values in the struct. */ - -struct section_offsets - { - CORE_ADDR offsets[1]; /* As many as needed. */ - }; - -#define ANOFFSET(secoff, whichone) (secoff->offsets[whichone]) - -/* Each source file or header is represented by a struct symtab. - These objects are chained through the `next' field. */ - -struct symtab - { - - /* Chain of all existing symtabs. */ - - struct symtab *next; - - /* List of all symbol scope blocks for this symtab. May be shared - between different symtabs (and normally is for all the symtabs - in a given compilation unit). */ - - struct blockvector *blockvector; - - /* Table mapping core addresses to line numbers for this file. - Can be NULL if none. Never shared between different symtabs. */ - - struct linetable *linetable; - - /* Section in objfile->section_offsets for the blockvector and - the linetable. */ - - int block_line_section; - - /* If several symtabs share a blockvector, exactly one of them - should be designed the primary, so that the blockvector - is relocated exactly once by objfile_relocate. */ - - int primary; - - /* Name of this source file. */ - - char *filename; - - /* Directory in which it was compiled, or NULL if we don't know. */ - - char *dirname; - - /* This component says how to free the data we point to: - free_contents => do a tree walk and free each object. - free_nothing => do nothing; some other symtab will free - the data this one uses. - free_linetable => free just the linetable. FIXME: Is this redundant - with the primary field? */ - - enum free_code - { - free_nothing, free_contents, free_linetable - } - free_code; - - /* Pointer to one block of storage to be freed, if nonzero. */ - /* This is IN ADDITION to the action indicated by free_code. */ - - char *free_ptr; - - /* Total number of lines found in source file. */ - - int nlines; - - /* line_charpos[N] is the position of the (N-1)th line of the - source file. "position" means something we can lseek() to; it - is not guaranteed to be useful any other way. */ - - int *line_charpos; - - /* Language of this source file. */ - - enum language language; - - /* String of version information. May be zero. */ - - char *version; - - /* Full name of file as found by searching the source path. - NULL if not yet known. */ - - char *fullname; - - /* Object file from which this symbol information was read. */ - - 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 -#define LINETABLE(symtab) (symtab)->linetable - - -/* Each source file that has not been fully read in is represented by - a partial_symtab. This contains the information on where in the - executable the debugging symbols for a specific file are, and a - list of names of global symbols which are located in this file. - They are all chained on partial symtab lists. - - Even after the source file has been read into a symtab, the - partial_symtab remains around. They are allocated on an obstack, - psymbol_obstack. FIXME, this is bad for dynamic linking or VxWorks- - style execution of a bunch of .o's. */ - -struct partial_symtab -{ - - /* Chain of all existing partial symtabs. */ - - struct partial_symtab *next; - - /* Name of the source file which this partial_symtab defines */ - - char *filename; - - /* Information about the object file from which symbols should be read. */ - - struct objfile *objfile; - - /* Set of relocation offsets to apply to each section. */ - - struct section_offsets *section_offsets; - - /* Range of text addresses covered by this file; texthigh is the - beginning of the next section. */ - - CORE_ADDR textlow; - CORE_ADDR texthigh; - - /* Array of pointers to all of the partial_symtab's which this one - depends on. Since this array can only be set to previous or - the current (?) psymtab, this dependency tree is guaranteed not - to have any loops. "depends on" means that symbols must be read - for the dependencies before being read for this psymtab; this is - for type references in stabs, where if foo.c includes foo.h, declarations - in foo.h may use type numbers defined in foo.c. For other debugging - formats there may be no need to use dependencies. */ - - struct partial_symtab **dependencies; - - int number_of_dependencies; - - /* Global symbol list. This list will be sorted after readin to - improve access. Binary search will be the usual method of - finding a symbol within it. globals_offset is an integer offset - within global_psymbols[]. */ - - int globals_offset; - int n_global_syms; - - /* Static symbol list. This list will *not* be sorted after readin; - to find a symbol in it, exhaustive search must be used. This is - reasonable because searches through this list will eventually - lead to either the read in of a files symbols for real (assumed - to take a *lot* of time; check) or an error (and we don't care - how long errors take). This is an offset and size within - static_psymbols[]. */ - - int statics_offset; - int n_static_syms; - - /* Pointer to symtab eventually allocated for this source file, 0 if - !readin or if we haven't looked for the symtab after it was readin. */ - - struct symtab *symtab; - - /* Pointer to function which will read in the symtab corresponding to - this psymtab. */ - - void (*read_symtab) PARAMS ((struct partial_symtab *)); - - /* Information that lets read_symtab() locate the part of the symbol table - that this psymtab corresponds to. This information is private to the - format-dependent symbol reading routines. For further detail examine - the various symbol reading modules. Should really be (void *) but is - (char *) as with other such gdb variables. (FIXME) */ - - char *read_symtab_private; - - /* Non-zero if the symtab corresponding to this psymtab has been readin */ - - unsigned char readin; -}; - -/* A fast way to get from a psymtab to its symtab (after the first time). */ -#define PSYMTAB_TO_SYMTAB(pst) \ - ((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst)) - - -/* The virtual function table is now an array of structures which have the - form { int16 offset, delta; void *pfn; }. - - In normal virtual function tables, OFFSET is unused. - DELTA is the amount which is added to the apparent object's base - address in order to point to the actual object to which the - virtual function should be applied. - PFN is a pointer to the virtual function. - - Note that this macro is g++ specific (FIXME). */ - -#define VTBL_FNADDR_OFFSET 2 - -/* Macro that yields non-zero value iff NAME is the prefix for C++ operator - names. If you leave out the parenthesis here you will lose! - Currently 'o' 'p' CPLUS_MARKER is used for both the symbol in the - symbol-file and the names in gdb's symbol table. - Note that this macro is g++ specific (FIXME). */ - -#define OPNAME_PREFIX_P(NAME) \ - ((NAME)[0] == 'o' && (NAME)[1] == 'p' && (NAME)[2] == CPLUS_MARKER) - -/* Macro that yields non-zero value iff NAME is the prefix for C++ vtbl - names. Note that this macro is g++ specific (FIXME). - '_vt$' is the old cfront-style vtables; '_VT$' is the new - style, using thunks (where '$' is really CPLUS_MARKER). */ - -#define VTBL_PREFIX_P(NAME) \ - ((NAME)[3] == CPLUS_MARKER && (NAME)[0] == '_' \ - && (((NAME)[1] == 'V' && (NAME)[2] == 'T') \ - || ((NAME)[1] == 'v' && (NAME)[2] == 't'))) - -/* Macro that yields non-zero value iff NAME is the prefix for C++ destructor - names. Note that this macro is g++ specific (FIXME). */ - -#define DESTRUCTOR_PREFIX_P(NAME) \ - ((NAME)[0] == '_' && (NAME)[1] == CPLUS_MARKER && (NAME)[2] == '_') - - -/* External variables and functions for the objects described above. */ - -/* This symtab variable specifies the current file for printing source lines */ - -extern struct symtab *current_source_symtab; - -/* This is the next line to print for listing source lines. */ - -extern int current_source_line; - -/* See the comment in symfile.c about how current_objfile is used. */ - -extern struct objfile *current_objfile; - -/* From utils.c. */ -extern int demangle; -extern int asm_demangle; - -extern struct symtab * -lookup_symtab PARAMS ((char *)); - -extern struct symbol * -lookup_symbol PARAMS ((const char *, const struct block *, - const enum namespace, int *, struct symtab **)); - -extern struct symbol * -lookup_block_symbol PARAMS ((const struct block *, const char *, - const enum namespace)); - -extern struct type * -lookup_struct PARAMS ((char *, struct block *)); - -extern struct type * -lookup_union PARAMS ((char *, struct block *)); - -extern struct type * -lookup_enum PARAMS ((char *, struct block *)); - -extern struct symbol * -block_function PARAMS ((struct block *)); - -extern struct symbol * -find_pc_function PARAMS ((CORE_ADDR)); - -extern int find_pc_partial_function - PARAMS ((CORE_ADDR, char **, CORE_ADDR *, CORE_ADDR *)); - -extern void -clear_pc_function_cache PARAMS ((void)); - -extern struct partial_symtab * -lookup_partial_symtab PARAMS ((char *)); - -extern struct partial_symtab * -find_pc_psymtab PARAMS ((CORE_ADDR)); - -extern struct symtab * -find_pc_symtab PARAMS ((CORE_ADDR)); - -extern struct partial_symbol * -find_pc_psymbol PARAMS ((struct partial_symtab *, CORE_ADDR)); - -extern int -find_pc_line_pc_range PARAMS ((CORE_ADDR, CORE_ADDR *, CORE_ADDR *)); - -extern int -contained_in PARAMS ((struct block *, struct block *)); - -extern void -reread_symbols PARAMS ((void)); - -/* Macro for name of symbol to indicate a file compiled with gcc. */ -#ifndef GCC_COMPILED_FLAG_SYMBOL -#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled." -#endif - -/* Macro for name of symbol to indicate a file compiled with gcc2. */ -#ifndef GCC2_COMPILED_FLAG_SYMBOL -#define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled." -#endif - -/* Functions for dealing with the minimal symbol table, really a misc - address<->symbol mapping for things we don't have debug symbols for. */ - -extern void prim_record_minimal_symbol PARAMS ((const char *, CORE_ADDR, - enum minimal_symbol_type, - struct objfile *)); - -extern void prim_record_minimal_symbol_and_info - PARAMS ((const char *, CORE_ADDR, - enum minimal_symbol_type, - char *info, int section, - struct objfile *)); - -extern struct minimal_symbol * -lookup_minimal_symbol PARAMS ((const char *, struct objfile *)); - -extern struct minimal_symbol * -lookup_minimal_symbol_by_pc PARAMS ((CORE_ADDR)); - -extern struct minimal_symbol * -lookup_solib_trampoline_symbol_by_pc PARAMS ((CORE_ADDR)); - -extern CORE_ADDR -find_solib_trampoline_target PARAMS ((CORE_ADDR)); - -extern void -init_minimal_symbol_collection PARAMS ((void)); - -extern void -discard_minimal_symbols PARAMS ((int)); - -extern void -install_minimal_symbols PARAMS ((struct objfile *)); - -struct symtab_and_line -{ - struct symtab *symtab; - - /* 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. */ - int line; - - CORE_ADDR pc; - CORE_ADDR end; -}; - -struct symtabs_and_lines -{ - struct symtab_and_line *sals; - int nelts; -}; - -/* 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)); - -/* 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. */ - -extern struct symbol * -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_range PARAMS ((struct symtab_and_line, - CORE_ADDR *, CORE_ADDR *)); - -extern void -resolve_sal_pc PARAMS ((struct symtab_and_line *)); - -/* Given a string, return the line specified by it. For commands like "list" - and "breakpoint". */ - -extern struct symtabs_and_lines -decode_line_spec PARAMS ((char *, int)); - -extern struct symtabs_and_lines -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 - -void -maintenance_print_symbols PARAMS ((char *, int)); - -void -maintenance_print_psymbols PARAMS ((char *, int)); - -void -maintenance_print_msymbols PARAMS ((char *, int)); - -void -maintenance_print_objfiles PARAMS ((char *, int)); - -void -maintenance_check_symtabs PARAMS ((char *, int)); - -#endif - -extern void -free_symtab PARAMS ((struct symtab *)); - -/* Symbol-reading stuff in symfile.c and solib.c. */ - -extern struct symtab * -psymtab_to_symtab PARAMS ((struct partial_symtab *)); - -extern void -clear_solib PARAMS ((void)); - -extern struct objfile * -symbol_file_add PARAMS ((char *, int, CORE_ADDR, int, int, int)); - -/* source.c */ - -extern int -identify_source_line PARAMS ((struct symtab *, int, int, CORE_ADDR)); - -extern void -print_source_lines PARAMS ((struct symtab *, int, int, int)); - -extern void -forget_cached_source_info PARAMS ((void)); - -extern void -select_source_symtab PARAMS ((struct symtab *)); - -extern char **make_symbol_completion_list PARAMS ((char *, char *)); - -/* symtab.c */ - -extern struct partial_symtab * -find_main_psymtab PARAMS ((void)); - -/* blockframe.c */ - -extern struct blockvector * -blockvector_for_pc PARAMS ((CORE_ADDR, int *)); - -/* symfile.c */ - -extern void -clear_symtab_users PARAMS ((void)); - -extern enum language -deduce_language_from_filename PARAMS ((char *)); - -#endif /* !defined(SYMTAB_H) */ diff --git a/gnu/usr.bin/gdb/gdb/target.c b/gnu/usr.bin/gdb/gdb/target.c deleted file mode 100644 index e3c6b34..0000000 --- a/gnu/usr.bin/gdb/gdb/target.c +++ /dev/null @@ -1,1316 +0,0 @@ -/* Select target systems and architectures at runtime for GDB. - Copyright 1990, 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include -#include -#include "target.h" -#include "gdbcmd.h" -#include "symtab.h" -#include "inferior.h" -#include "bfd.h" -#include "symfile.h" -#include "objfiles.h" -#include "wait.h" -#include - -extern int errno; - -static void -target_info PARAMS ((char *, int)); - -static void -cleanup_target PARAMS ((struct target_ops *)); - -static void -maybe_kill_then_create_inferior PARAMS ((char *, char *, char **)); - -static void -maybe_kill_then_attach PARAMS ((char *, int)); - -static void -kill_or_be_killed PARAMS ((int)); - -static void -default_terminal_info PARAMS ((char *, int)); - -static int -nosymbol PARAMS ((char *, CORE_ADDR *)); - -static void -tcomplain PARAMS ((void)); - -static int -nomemory PARAMS ((CORE_ADDR, char *, int, int)); - -static int -return_zero PARAMS ((void)); - -static void -ignore PARAMS ((void)); - -static void -target_command PARAMS ((char *, int)); - -static struct target_ops * -find_default_run_target PARAMS ((char *)); - -/* Pointer to array of target architecture structures; the size of the - array; the current index into the array; the allocated size of the - array. */ -struct target_ops **target_structs; -unsigned target_struct_size; -unsigned target_struct_index; -unsigned target_struct_allocsize; -#define DEFAULT_ALLOCSIZE 10 - -/* The initial current target, so that there is always a semi-valid - current target. */ - -struct target_ops dummy_target = {"None", "None", "", - 0, 0, /* open, close */ - find_default_attach, 0, /* attach, detach */ - 0, 0, /* resume, wait */ - 0, 0, 0, /* registers */ - 0, 0, /* memory */ - 0, 0, /* bkpts */ - 0, 0, 0, 0, 0, /* terminal */ - 0, 0, /* kill, load */ - 0, /* lookup_symbol */ - find_default_create_inferior, /* create_inferior */ - 0, /* mourn_inferior */ - 0, /* can_run */ - 0, /* notice_signals */ - dummy_stratum, 0, /* stratum, next */ - 0, 0, 0, 0, 0, /* all mem, mem, stack, regs, exec */ - 0, 0, /* section pointers */ - OPS_MAGIC, -}; - -/* The target structure we are currently using to talk to a process - or file or whatever "inferior" we have. */ - -struct target_ops *current_target; - -/* The stack of target structures that have been pushed. */ - -struct target_ops **current_target_stack; - -/* Command list for target. */ - -static struct cmd_list_element *targetlist = NULL; - -/* Nonzero if we are debugging an attached outside process - rather than an inferior. */ - -int attach_flag; - -/* The user just typed 'target' without the name of a target. */ - -/* ARGSUSED */ -static void -target_command (arg, from_tty) - char *arg; - int from_tty; -{ - fputs_filtered ("Argument required (target name). Try `help target'\n", - gdb_stdout); -} - -/* Add a possible target architecture to the list. */ - -void -add_target (t) - struct target_ops *t; -{ - if (t->to_magic != OPS_MAGIC) - { - fprintf_unfiltered(gdb_stderr, "Magic number of %s target struct wrong\n", - t->to_shortname); - abort(); - } - - if (!target_structs) - { - target_struct_allocsize = DEFAULT_ALLOCSIZE; - target_structs = (struct target_ops **) xmalloc - (target_struct_allocsize * sizeof (*target_structs)); - } - if (target_struct_size >= target_struct_allocsize) - { - target_struct_allocsize *= 2; - target_structs = (struct target_ops **) - xrealloc ((char *) target_structs, - target_struct_allocsize * sizeof (*target_structs)); - } - target_structs[target_struct_size++] = t; - cleanup_target (t); - - if (targetlist == NULL) - add_prefix_cmd ("target", class_run, target_command, - "Connect to a target machine or process.\n\ -The first argument is the type or protocol of the target machine.\n\ -Remaining arguments are interpreted by the target protocol. For more\n\ -information on the arguments for a particular protocol, type\n\ -`help target ' followed by the protocol name.", - &targetlist, "target ", 0, &cmdlist); - add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc, &targetlist); -} - -/* Stub functions */ - -static void -ignore () -{ -} - -/* ARGSUSED */ -static int -nomemory (memaddr, myaddr, len, write) - CORE_ADDR memaddr; - char *myaddr; - int len; - int write; -{ - errno = EIO; /* Can't read/write this location */ - return 0; /* No bytes handled */ -} - -static void -tcomplain () -{ - error ("You can't do that when your target is `%s'", - current_target->to_shortname); -} - -void -noprocess () -{ - error ("You can't do that without a process to debug"); -} - -/* ARGSUSED */ -static int -nosymbol (name, addrp) - char *name; - CORE_ADDR *addrp; -{ - return 1; /* Symbol does not exist in target env */ -} - -/* ARGSUSED */ -static void -default_terminal_info (args, from_tty) - char *args; - int from_tty; -{ - printf_unfiltered("No saved terminal information.\n"); -} - -#if 0 -/* With strata, this function is no longer needed. FIXME. */ -/* This is the default target_create_inferior function. It looks up - the stack for some target that cares to create inferiors, then - calls it -- or complains if not found. */ - -static void -upstack_create_inferior (exec, args, env) - char *exec; - char *args; - char **env; -{ - struct target_ops *t; - - for (t = current_target; - t; - t = t->to_next) - { - if (t->to_create_inferior != upstack_create_inferior) - { - t->to_create_inferior (exec, args, env); - return; - } - - } - tcomplain(); -} -#endif - -/* This is the default target_create_inferior and target_attach function. - If the current target is executing, it asks whether to kill it off. - If this function returns without calling error(), it has killed off - the target, and the operation should be attempted. */ - -static void -kill_or_be_killed (from_tty) - int from_tty; -{ - if (target_has_execution) - { - printf_unfiltered ("You are already running a program:\n"); - target_files_info (); - if (query ("Kill it? ")) { - target_kill (); - if (target_has_execution) - error ("Killing the program did not help."); - return; - } else { - error ("Program not killed."); - } - } - tcomplain(); -} - -static void -maybe_kill_then_attach (args, from_tty) - char *args; - int from_tty; -{ - kill_or_be_killed (from_tty); - target_attach (args, from_tty); -} - -static void -maybe_kill_then_create_inferior (exec, args, env) - char *exec; - char *args; - char **env; -{ - kill_or_be_killed (0); - target_create_inferior (exec, args, env); -} - -/* 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. */ - -static void -cleanup_target (t) - struct target_ops *t; -{ - - /* Check magic number. If wrong, it probably means someone changed - the struct definition, but not all the places that initialize one. */ - if (t->to_magic != OPS_MAGIC) - { - fprintf_unfiltered(gdb_stderr, "Magic number of %s target struct wrong\n", - t->to_shortname); - abort(); - } - -#define de_fault(field, value) \ - if (!t->field) t->field = value - - /* FIELD DEFAULT VALUE */ - - de_fault (to_open, (void (*)())tcomplain); - de_fault (to_close, (void (*)())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_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_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_create_inferior, maybe_kill_then_create_inferior); - de_fault (to_mourn_inferior, (void (*)())noprocess); - de_fault (to_can_run, return_zero); - de_fault (to_notice_signals, (void (*)())ignore); - de_fault (to_next, 0); - de_fault (to_has_all_memory, 0); - de_fault (to_has_memory, 0); - de_fault (to_has_stack, 0); - de_fault (to_has_registers, 0); - de_fault (to_has_execution, 0); - -#undef de_fault -} - -/* Push a new target type into the stack of the existing target accessors, - possibly superseding some of the existing accessors. - - Result is zero if the pushed target ended up on top of the stack, - nonzero if at least one target is on top of it. - - Rather than allow an empty stack, we always have the dummy target at - the bottom stratum, so we can call the function vectors without - checking them. */ - -int -push_target (t) - struct target_ops *t; -{ - struct target_ops *st, *prev; - - for (prev = 0, st = current_target; - st; - prev = st, st = st->to_next) { - if ((int)(t->to_stratum) >= (int)(st->to_stratum)) - break; - } - - while (t->to_stratum == st->to_stratum) { - /* There's already something on this stratum. Close it off. */ - (st->to_close) (0); - if (prev) - prev->to_next = st->to_next; /* Unchain old target_ops */ - else - current_target = st->to_next; /* Unchain first on list */ - st = st->to_next; - } - - /* We have removed all targets in our stratum, now add ourself. */ - t->to_next = st; - if (prev) - prev->to_next = t; - else - current_target = t; - - cleanup_target (current_target); - return prev != 0; -} - -/* Remove a target_ops vector from the stack, wherever it may be. - Return how many times it was removed (0 or 1 unless bug). */ - -int -unpush_target (t) - struct target_ops *t; -{ - struct target_ops *u, *v; - int result = 0; - - for (u = current_target, v = 0; - u; - v = u, u = u->to_next) - if (u == t) - { - if (v == 0) - pop_target(); /* unchain top copy */ - else { - (t->to_close)(0); /* Let it clean up */ - v->to_next = t->to_next; /* unchain middle copy */ - } - result++; - } - return result; -} - -void -pop_target () -{ - (current_target->to_close)(0); /* Let it clean up */ - current_target = current_target->to_next; -#if 0 - /* This will dump core if ever called--push_target expects current_target - to be non-NULL. But I don't think it's needed; I don't see how the - dummy_target could ever be removed from the stack. */ - if (!current_target) /* At bottom, push dummy. */ - push_target (&dummy_target); -#endif -} - -#undef MIN -#define MIN(A, B) (((A) <= (B)) ? (A) : (B)) - -/* target_read_string -- read a null terminated string, up to LEN bytes, - from MEMADDR in target. Set *ERRNOP to the errno code, or 0 if successful. - Set *STRING to a pointer to malloc'd memory containing the data; the caller - is responsible for freeing it. Return the number of bytes successfully - read. */ - -int -target_read_string (memaddr, string, len, errnop) - CORE_ADDR memaddr; - char **string; - int len; - int *errnop; -{ - int tlen, origlen, offset, i; - char buf[4]; - int errcode = 0; - char *buffer; - int buffer_allocated; - char *bufptr; - unsigned int nbytes_read = 0; - - /* Small for testing. */ - buffer_allocated = 4; - buffer = xmalloc (buffer_allocated); - bufptr = buffer; - - origlen = len; - - while (len > 0) - { - tlen = MIN (len, 4 - (memaddr & 3)); - offset = memaddr & 3; - - errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0); - if (errcode != 0) - goto done; - - if (bufptr - buffer + tlen > buffer_allocated) - { - unsigned int bytes; - bytes = bufptr - buffer; - buffer_allocated *= 2; - buffer = xrealloc (buffer, buffer_allocated); - bufptr = buffer + bytes; - } - - for (i = 0; i < tlen; i++) - { - *bufptr++ = buf[i + offset]; - if (buf[i + offset] == '\000') - { - nbytes_read += i + 1; - goto done; - } - } - - memaddr += tlen; - len -= tlen; - nbytes_read += tlen; - } - done: - if (errnop != NULL) - *errnop = errcode; - if (string != NULL) - *string = buffer; - return nbytes_read; -} - -/* Read LEN bytes of target memory at address MEMADDR, placing the results in - GDB's memory at MYADDR. Returns either 0 for success or an errno value - if any error occurs. - - If an error occurs, no guarantee is made about the contents of the data at - MYADDR. In particular, the caller should not depend upon partial reads - filling the buffer with good data. There is no way for the caller to know - how much good data might have been transfered anyway. Callers that can - deal with partial reads should call target_read_memory_partial. */ - -int -target_read_memory (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - return target_xfer_memory (memaddr, myaddr, len, 0); -} - -/* Read LEN bytes of target memory at address MEMADDR, placing the results - in GDB's memory at MYADDR. Returns a count of the bytes actually read, - and optionally an errno value in the location pointed to by ERRNOPTR - if ERRNOPTR is non-null. */ - -int -target_read_memory_partial (memaddr, myaddr, len, errnoptr) - CORE_ADDR memaddr; - char *myaddr; - int len; - int *errnoptr; -{ - int nread; /* Number of bytes actually read. */ - int errcode; /* Error from last read. */ - - /* First try a complete read. */ - errcode = target_xfer_memory (memaddr, myaddr, len, 0); - if (errcode == 0) - { - /* Got it all. */ - nread = len; - } - else - { - /* 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); - } - /* If an error, the last read was unsuccessful, so adjust count. */ - if (errcode != 0) - { - nread--; - } - } - if (errnoptr != NULL) - { - *errnoptr = errcode; - } - return (nread); -} - -int -target_write_memory (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - return target_xfer_memory (memaddr, myaddr, len, 1); -} - -/* 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 - business with curlen: if an early target says "no, but I have a - boundary overlapping this xfer" then we shorten what we offer to - the subsequent targets so the early guy will get a chance at the - tail before the subsequent ones do. - - Result is 0 or errno value. */ - -int -target_xfer_memory (memaddr, myaddr, len, write) - CORE_ADDR memaddr; - char *myaddr; - int len; - int write; -{ - int curlen; - int res; - struct target_ops *t; - - /* to_xfer_memory is not guaranteed to set errno, even when it returns - 0. */ - errno = 0; - - /* The quick case is that the top target does it all. */ - res = current_target->to_xfer_memory - (memaddr, myaddr, len, write, current_target); - if (res == len) - return 0; - - if (res > 0) - goto bump; - /* If res <= 0 then we call it again in the loop. Ah well. */ - - for (; len > 0;) - { - curlen = len; /* Want to do it all */ - for (t = current_target; - t; - t = t->to_has_all_memory? 0: t->to_next) - { - res = t->to_xfer_memory(memaddr, myaddr, curlen, write, t); - if (res > 0) break; /* Handled all or part of xfer */ - if (res == 0) continue; /* Handled none */ - curlen = -res; /* Could handle once we get past res bytes */ - } - if (res <= 0) - { - /* If this address is for nonexistent memory, - read zeros if reading, or do nothing if writing. Return error. */ - if (!write) - memset (myaddr, 0, len); - if (errno == 0) - return EIO; - else - return errno; - } -bump: - memaddr += res; - myaddr += res; - len -= res; - } - return 0; /* We managed to cover it all somehow. */ -} - - -/* ARGSUSED */ -static void -target_info (args, from_tty) - char *args; - int from_tty; -{ - struct target_ops *t; - int has_all_mem = 0; - - if (symfile_objfile != NULL) - printf_unfiltered ("Symbols from \"%s\".\n", symfile_objfile->name); - -#ifdef FILES_INFO_HOOK - if (FILES_INFO_HOOK ()) - return; -#endif - - for (t = current_target; - t; - t = t->to_next) - { - if ((int)(t->to_stratum) <= (int)dummy_stratum) - continue; - if (has_all_mem) - printf_unfiltered("\tWhile running this, GDB does not access memory from...\n"); - printf_unfiltered("%s:\n", t->to_longname); - (t->to_files_info)(t); - has_all_mem = t->to_has_all_memory; - } -} - -/* This is to be called by the open routine before it does - anything. */ - -void -target_preopen (from_tty) - int from_tty; -{ - dont_repeat(); - - if (target_has_execution) - { - if (query ("A program is being debugged already. Kill it? ")) - target_kill (); - else - error ("Program not killed."); - } - - /* Calling target_kill may remove the target from the stack. But if - it doesn't (which seems like a win for UDI), remove it now. */ - - if (target_has_execution) - pop_target (); -} - -/* Detach a target after doing deferred register stores. */ - -void -target_detach (args, from_tty) - char *args; - int from_tty; -{ - /* Handle any optimized stores to the inferior. */ -#ifdef DO_DEFERRED_STORES - DO_DEFERRED_STORES; -#endif - (current_target->to_detach) (args, from_tty); -} - -void -target_link (modname, t_reloc) - char *modname; - CORE_ADDR *t_reloc; -{ - if (STREQ(current_target->to_shortname, "rombug")) - { - (current_target->to_lookup_symbol) (modname, t_reloc); - if (*t_reloc == 0) - error("Unable to link to %s and get relocation in rombug", modname); - } - else - *t_reloc = (CORE_ADDR)-1; -} - -/* Look through the list of possible targets for a target that can - execute a run or attach command without any other data. This is - used to locate the default process stratum. - - Result is always valid (error() is called for errors). */ - -static struct target_ops * -find_default_run_target (do_mesg) - char *do_mesg; -{ - struct target_ops **t; - struct target_ops *runable = NULL; - int count; - - count = 0; - - for (t = target_structs; t < target_structs + target_struct_size; - ++t) - { - if (target_can_run(*t)) - { - runable = *t; - ++count; - } - } - - if (count != 1) - error ("Don't know how to %s. Try \"help target\".", do_mesg); - - return runable; -} - -void -find_default_attach (args, from_tty) - char *args; - int from_tty; -{ - struct target_ops *t; - - t = find_default_run_target("attach"); - (t->to_attach) (args, from_tty); - return; -} - -void -find_default_create_inferior (exec_file, allargs, env) - char *exec_file; - char *allargs; - char **env; -{ - struct target_ops *t; - - t = find_default_run_target("run"); - (t->to_create_inferior) (exec_file, allargs, env); - return; -} - -static int -return_zero () -{ - return 0; -} - -struct target_ops * -find_core_target () -{ - struct target_ops **t; - struct target_ops *runable = NULL; - int count; - - count = 0; - - for (t = target_structs; t < target_structs + target_struct_size; - ++t) - { -#ifdef KERNEL_DEBUG - if ((*t)->to_stratum == (kernel_debugging ? kcore_stratum : core_stratum)) -#else - if ((*t)->to_stratum == core_stratum) -#endif - { - runable = *t; - ++count; - } - } - - return(count == 1 ? runable : NULL); -} - -/* The inferior process has died. Long live the inferior! */ - -void -generic_mourn_inferior () -{ - extern int show_breakpoint_hit_counts; - - inferior_pid = 0; - attach_flag = 0; - breakpoint_init_inferior (); - registers_changed (); - -#ifdef CLEAR_DEFERRED_STORES - /* Delete any pending stores to the inferior... */ - CLEAR_DEFERRED_STORES; -#endif - - reopen_exec_file (); - reinit_frame_cache (); - - /* It is confusing to the user for ignore counts to stick around - from previous runs of the inferior. So clear them. */ - /* However, it is more confusing for the ignore counts to disappear when - using hit counts. So don't clear them if we're counting hits. */ - if (!show_breakpoint_hit_counts) - breakpoint_clear_ignore_counts (); -} - -/* This table must match in order and size the signals in enum target_signal - in target.h. */ -static struct { - char *name; - char *string; - } signals [] = -{ - {"0", "Signal 0"}, - {"SIGHUP", "Hangup"}, - {"SIGINT", "Interrupt"}, - {"SIGQUIT", "Quit"}, - {"SIGILL", "Illegal instruction"}, - {"SIGTRAP", "Trace/breakpoint trap"}, - {"SIGABRT", "Aborted"}, - {"SIGEMT", "Emulation trap"}, - {"SIGFPE", "Arithmetic exception"}, - {"SIGKILL", "Killed"}, - {"SIGBUS", "Bus error"}, - {"SIGSEGV", "Segmentation fault"}, - {"SIGSYS", "Bad system call"}, - {"SIGPIPE", "Broken pipe"}, - {"SIGALRM", "Alarm clock"}, - {"SIGTERM", "Terminated"}, - {"SIGURG", "Urgent I/O condition"}, - {"SIGSTOP", "Stopped (signal)"}, - {"SIGTSTP", "Stopped (user)"}, - {"SIGCONT", "Continued"}, - {"SIGCHLD", "Child status changed"}, - {"SIGTTIN", "Stopped (tty input)"}, - {"SIGTTOU", "Stopped (tty output)"}, - {"SIGIO", "I/O possible"}, - {"SIGXCPU", "CPU time limit exceeded"}, - {"SIGXFSZ", "File size limit exceeded"}, - {"SIGVTALRM", "Virtual timer expired"}, - {"SIGPROF", "Profiling timer expired"}, - {"SIGWINCH", "Window size changed"}, - {"SIGLOST", "Resource lost"}, - {"SIGUSR1", "User defined signal 1"}, - {"SIGUSR2", "User defined signal 2"}, - {"SIGPWR", "Power fail/restart"}, - {"SIGPOLL", "Pollable event occurred"}, - {"SIGWIND", "SIGWIND"}, - {"SIGPHONE", "SIGPHONE"}, - {"SIGWAITING", "Process's LWPs are blocked"}, - {"SIGLWP", "Signal LWP"}, - {"SIGDANGER", "Swap space dangerously low"}, - {"SIGGRANT", "Monitor mode granted"}, - {"SIGRETRACT", "Need to relinguish monitor mode"}, - {"SIGMSG", "Monitor mode data available"}, - {"SIGSOUND", "Sound completed"}, - {"SIGSAK", "Secure attention"}, - {NULL, "Unknown signal"}, - {NULL, "Internal error: printing TARGET_SIGNAL_DEFAULT"}, - - /* Last entry, used to check whether the table is the right size. */ - {NULL, "TARGET_SIGNAL_MAGIC"} -}; - -/* Return the string for a signal. */ -char * -target_signal_to_string (sig) - enum target_signal sig; -{ - return signals[sig].string; -} - -/* Return the name for a signal. */ -char * -target_signal_to_name (sig) - enum target_signal sig; -{ - if (sig == TARGET_SIGNAL_UNKNOWN) - /* I think the code which prints this will always print it along with - the string, so no need to be verbose. */ - return "?"; - return signals[sig].name; -} - -/* Given a name, return its signal. */ -enum target_signal -target_signal_from_name (name) - char *name; -{ - enum target_signal sig; - - /* It's possible we also should allow "SIGCLD" as well as "SIGCHLD" - for TARGET_SIGNAL_SIGCHLD. SIGIOT, on the other hand, is more - questionable; seems like by now people should call it SIGABRT - instead. */ - - /* This ugly cast brought to you by the native VAX compiler. */ - for (sig = TARGET_SIGNAL_HUP; - signals[sig].name != NULL; - sig = (enum target_signal)((int)sig + 1)) - if (STREQ (name, signals[sig].name)) - return sig; - return TARGET_SIGNAL_UNKNOWN; -} - -/* The following functions are to help certain targets deal - with the signal/waitstatus stuff. They could just as well be in - a file called native-utils.c or unixwaitstatus-utils.c or whatever. */ - -/* Convert host signal to our signals. */ -enum target_signal -target_signal_from_host (hostsig) - int hostsig; -{ - /* A switch statement would make sense but would require special kludges - to deal with the cases where more than one signal has the same number. */ - - if (hostsig == 0) return TARGET_SIGNAL_0; - -#if defined (SIGHUP) - if (hostsig == SIGHUP) return TARGET_SIGNAL_HUP; -#endif -#if defined (SIGINT) - if (hostsig == SIGINT) return TARGET_SIGNAL_INT; -#endif -#if defined (SIGQUIT) - if (hostsig == SIGQUIT) return TARGET_SIGNAL_QUIT; -#endif -#if defined (SIGILL) - if (hostsig == SIGILL) return TARGET_SIGNAL_ILL; -#endif -#if defined (SIGTRAP) - if (hostsig == SIGTRAP) return TARGET_SIGNAL_TRAP; -#endif -#if defined (SIGABRT) - if (hostsig == SIGABRT) return TARGET_SIGNAL_ABRT; -#endif -#if defined (SIGEMT) - if (hostsig == SIGEMT) return TARGET_SIGNAL_EMT; -#endif -#if defined (SIGFPE) - if (hostsig == SIGFPE) return TARGET_SIGNAL_FPE; -#endif -#if defined (SIGKILL) - if (hostsig == SIGKILL) return TARGET_SIGNAL_KILL; -#endif -#if defined (SIGBUS) - if (hostsig == SIGBUS) return TARGET_SIGNAL_BUS; -#endif -#if defined (SIGSEGV) - if (hostsig == SIGSEGV) return TARGET_SIGNAL_SEGV; -#endif -#if defined (SIGSYS) - if (hostsig == SIGSYS) return TARGET_SIGNAL_SYS; -#endif -#if defined (SIGPIPE) - if (hostsig == SIGPIPE) return TARGET_SIGNAL_PIPE; -#endif -#if defined (SIGALRM) - if (hostsig == SIGALRM) return TARGET_SIGNAL_ALRM; -#endif -#if defined (SIGTERM) - if (hostsig == SIGTERM) return TARGET_SIGNAL_TERM; -#endif -#if defined (SIGUSR1) - if (hostsig == SIGUSR1) return TARGET_SIGNAL_USR1; -#endif -#if defined (SIGUSR2) - if (hostsig == SIGUSR2) return TARGET_SIGNAL_USR2; -#endif -#if defined (SIGCLD) - if (hostsig == SIGCLD) return TARGET_SIGNAL_CHLD; -#endif -#if defined (SIGCHLD) - if (hostsig == SIGCHLD) return TARGET_SIGNAL_CHLD; -#endif -#if defined (SIGPWR) - if (hostsig == SIGPWR) return TARGET_SIGNAL_PWR; -#endif -#if defined (SIGWINCH) - if (hostsig == SIGWINCH) return TARGET_SIGNAL_WINCH; -#endif -#if defined (SIGURG) - if (hostsig == SIGURG) return TARGET_SIGNAL_URG; -#endif -#if defined (SIGIO) - if (hostsig == SIGIO) return TARGET_SIGNAL_IO; -#endif -#if defined (SIGPOLL) - if (hostsig == SIGPOLL) return TARGET_SIGNAL_POLL; -#endif -#if defined (SIGSTOP) - if (hostsig == SIGSTOP) return TARGET_SIGNAL_STOP; -#endif -#if defined (SIGTSTP) - if (hostsig == SIGTSTP) return TARGET_SIGNAL_TSTP; -#endif -#if defined (SIGCONT) - if (hostsig == SIGCONT) return TARGET_SIGNAL_CONT; -#endif -#if defined (SIGTTIN) - if (hostsig == SIGTTIN) return TARGET_SIGNAL_TTIN; -#endif -#if defined (SIGTTOU) - if (hostsig == SIGTTOU) return TARGET_SIGNAL_TTOU; -#endif -#if defined (SIGVTALRM) - if (hostsig == SIGVTALRM) return TARGET_SIGNAL_VTALRM; -#endif -#if defined (SIGPROF) - if (hostsig == SIGPROF) return TARGET_SIGNAL_PROF; -#endif -#if defined (SIGXCPU) - if (hostsig == SIGXCPU) return TARGET_SIGNAL_XCPU; -#endif -#if defined (SIGXFSZ) - if (hostsig == SIGXFSZ) return TARGET_SIGNAL_XFSZ; -#endif -#if defined (SIGWIND) - if (hostsig == SIGWIND) return TARGET_SIGNAL_WIND; -#endif -#if defined (SIGPHONE) - if (hostsig == SIGPHONE) return TARGET_SIGNAL_PHONE; -#endif -#if defined (SIGLOST) - if (hostsig == SIGLOST) return TARGET_SIGNAL_LOST; -#endif -#if defined (SIGWAITING) - if (hostsig == SIGWAITING) return TARGET_SIGNAL_WAITING; -#endif -#if defined (SIGLWP) - if (hostsig == SIGLWP) return TARGET_SIGNAL_LWP; -#endif -#if defined (SIGDANGER) - if (hostsig == SIGDANGER) return TARGET_SIGNAL_DANGER; -#endif -#if defined (SIGGRANT) - if (hostsig == SIGGRANT) return TARGET_SIGNAL_GRANT; -#endif -#if defined (SIGRETRACT) - if (hostsig == SIGRETRACT) return TARGET_SIGNAL_RETRACT; -#endif -#if defined (SIGMSG) - if (hostsig == SIGMSG) return TARGET_SIGNAL_MSG; -#endif -#if defined (SIGSOUND) - if (hostsig == SIGSOUND) return TARGET_SIGNAL_SOUND; -#endif -#if defined (SIGSAK) - if (hostsig == SIGSAK) return TARGET_SIGNAL_SAK; -#endif - return TARGET_SIGNAL_UNKNOWN; -} - -int -target_signal_to_host (oursig) - enum target_signal oursig; -{ - switch (oursig) - { - case TARGET_SIGNAL_0: return 0; - -#if defined (SIGHUP) - case TARGET_SIGNAL_HUP: return SIGHUP; -#endif -#if defined (SIGINT) - case TARGET_SIGNAL_INT: return SIGINT; -#endif -#if defined (SIGQUIT) - case TARGET_SIGNAL_QUIT: return SIGQUIT; -#endif -#if defined (SIGILL) - case TARGET_SIGNAL_ILL: return SIGILL; -#endif -#if defined (SIGTRAP) - case TARGET_SIGNAL_TRAP: return SIGTRAP; -#endif -#if defined (SIGABRT) - case TARGET_SIGNAL_ABRT: return SIGABRT; -#endif -#if defined (SIGEMT) - case TARGET_SIGNAL_EMT: return SIGEMT; -#endif -#if defined (SIGFPE) - case TARGET_SIGNAL_FPE: return SIGFPE; -#endif -#if defined (SIGKILL) - case TARGET_SIGNAL_KILL: return SIGKILL; -#endif -#if defined (SIGBUS) - case TARGET_SIGNAL_BUS: return SIGBUS; -#endif -#if defined (SIGSEGV) - case TARGET_SIGNAL_SEGV: return SIGSEGV; -#endif -#if defined (SIGSYS) - case TARGET_SIGNAL_SYS: return SIGSYS; -#endif -#if defined (SIGPIPE) - case TARGET_SIGNAL_PIPE: return SIGPIPE; -#endif -#if defined (SIGALRM) - case TARGET_SIGNAL_ALRM: return SIGALRM; -#endif -#if defined (SIGTERM) - case TARGET_SIGNAL_TERM: return SIGTERM; -#endif -#if defined (SIGUSR1) - case TARGET_SIGNAL_USR1: return SIGUSR1; -#endif -#if defined (SIGUSR2) - case TARGET_SIGNAL_USR2: return SIGUSR2; -#endif -#if defined (SIGCHLD) || defined (SIGCLD) - case TARGET_SIGNAL_CHLD: -#if defined (SIGCHLD) - return SIGCHLD; -#else - return SIGCLD; -#endif -#endif /* SIGCLD or SIGCHLD */ -#if defined (SIGPWR) - case TARGET_SIGNAL_PWR: return SIGPWR; -#endif -#if defined (SIGWINCH) - case TARGET_SIGNAL_WINCH: return SIGWINCH; -#endif -#if defined (SIGURG) - case TARGET_SIGNAL_URG: return SIGURG; -#endif -#if defined (SIGIO) - case TARGET_SIGNAL_IO: return SIGIO; -#endif -#if defined (SIGPOLL) - case TARGET_SIGNAL_POLL: return SIGPOLL; -#endif -#if defined (SIGSTOP) - case TARGET_SIGNAL_STOP: return SIGSTOP; -#endif -#if defined (SIGTSTP) - case TARGET_SIGNAL_TSTP: return SIGTSTP; -#endif -#if defined (SIGCONT) - case TARGET_SIGNAL_CONT: return SIGCONT; -#endif -#if defined (SIGTTIN) - case TARGET_SIGNAL_TTIN: return SIGTTIN; -#endif -#if defined (SIGTTOU) - case TARGET_SIGNAL_TTOU: return SIGTTOU; -#endif -#if defined (SIGVTALRM) - case TARGET_SIGNAL_VTALRM: return SIGVTALRM; -#endif -#if defined (SIGPROF) - case TARGET_SIGNAL_PROF: return SIGPROF; -#endif -#if defined (SIGXCPU) - case TARGET_SIGNAL_XCPU: return SIGXCPU; -#endif -#if defined (SIGXFSZ) - case TARGET_SIGNAL_XFSZ: return SIGXFSZ; -#endif -#if defined (SIGWIND) - case TARGET_SIGNAL_WIND: return SIGWIND; -#endif -#if defined (SIGPHONE) - case TARGET_SIGNAL_PHONE: return SIGPHONE; -#endif -#if defined (SIGLOST) - case TARGET_SIGNAL_LOST: return SIGLOST; -#endif -#if defined (SIGWAITING) - case TARGET_SIGNAL_WAITING: return SIGWAITING; -#endif -#if defined (SIGLWP) - case TARGET_SIGNAL_LWP: return SIGLWP; -#endif -#if defined (SIGDANGER) - case TARGET_SIGNAL_DANGER: return SIGDANGER; -#endif -#if defined (SIGGRANT) - case TARGET_SIGNAL_GRANT: return SIGGRANT; -#endif -#if defined (SIGRETRACT) - case TARGET_SIGNAL_RETRACT: return SIGRETRACT; -#endif -#if defined (SIGMSG) - case TARGET_SIGNAL_MSG: return SIGMSG; -#endif -#if defined (SIGSOUND) - case TARGET_SIGNAL_SOUND: return SIGSOUND; -#endif -#if defined (SIGSAK) - case TARGET_SIGNAL_SAK: return SIGSAK; -#endif - default: - /* The user might be trying to do "signal SIGSAK" where this system - doesn't have SIGSAK. */ - warning ("Signal %s does not exist on this system.\n", - target_signal_to_name (oursig)); - return 0; - } -} - -/* Helper function for child_wait and the Lynx derivatives of child_wait. - HOSTSTATUS is the waitstatus from wait() or the equivalent; store our - translation of that in OURSTATUS. */ -void -store_waitstatus (ourstatus, hoststatus) - struct target_waitstatus *ourstatus; - int hoststatus; -{ -#ifdef CHILD_SPECIAL_WAITSTATUS - /* CHILD_SPECIAL_WAITSTATUS should return nonzero and set *OURSTATUS - if it wants to deal with hoststatus. */ - if (CHILD_SPECIAL_WAITSTATUS (ourstatus, hoststatus)) - return; -#endif - - if (WIFEXITED (hoststatus)) - { - ourstatus->kind = TARGET_WAITKIND_EXITED; - ourstatus->value.integer = WEXITSTATUS (hoststatus); - } - else if (!WIFSTOPPED (hoststatus)) - { - ourstatus->kind = TARGET_WAITKIND_SIGNALLED; - ourstatus->value.sig = target_signal_from_host (WTERMSIG (hoststatus)); - } - else - { - ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = target_signal_from_host (WSTOPSIG (hoststatus)); - } -} - - -/* Returns zero to leave the inferior alone, one to interrupt it. */ -int (*target_activity_function) PARAMS ((void)); -int target_activity_fd; - -/* Convert a normal process ID to a string. Returns the string in a static - buffer. */ - -char * -normal_pid_to_str (pid) - int pid; -{ - static char buf[30]; - - sprintf (buf, "process %d", pid); - - return buf; -} - -static char targ_desc[] = - "Names of targets and files being debugged.\n\ -Shows the entire stack of targets currently in use (including the exec-file,\n\ -core-file, and process, if any), as well as the symbol file name."; - -void -_initialize_targets () -{ - current_target = &dummy_target; - cleanup_target (current_target); - - add_info ("target", target_info, targ_desc); - add_info ("files", target_info, targ_desc); - - if (!STREQ (signals[TARGET_SIGNAL_LAST].string, "TARGET_SIGNAL_MAGIC")) - abort (); -} diff --git a/gnu/usr.bin/gdb/gdb/target.h b/gnu/usr.bin/gdb/gdb/target.h deleted file mode 100644 index 750be84..0000000 --- a/gnu/usr.bin/gdb/gdb/target.h +++ /dev/null @@ -1,649 +0,0 @@ -/* Interface between GDB and target environments, including files and processes - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by Cygnus Support. Written by John Gilmore. - -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 (TARGET_H) -#define TARGET_H - -/* This include file defines the interface between the main part - of the debugger, and the part which is target-specific, or - specific to the communications interface between us and the - target. - - A TARGET is an interface between the debugger and a particular - kind of file or process. Targets can be STACKED in STRATA, - so that more than one target can potentially respond to a request. - In particular, memory accesses will walk down the stack of targets - until they find a target that is interested in handling that particular - address. STRATA are artificial boundaries on the stack, within - which particular kinds of targets live. Strata exist so that - people don't get confused by pushing e.g. a process target and then - a file target, and wondering why they can't see the current values - of variables any more (the file target is handling them and they - never get to the process target). So when you push a file target, - it goes into the file stratum, which is always below the process - stratum. */ - -#include "bfd.h" - -enum strata { - dummy_stratum, /* The lowest of the low */ - file_stratum, /* Executable files, etc */ - core_stratum, /* Core dump files */ -#ifdef KERNEL_DEBUG - kcore_stratum, /* Kernel core files */ -#endif - process_stratum /* Executing processes */ -}; - -/* Stuff for target_wait. */ - -/* Generally, what has the program done? */ -enum target_waitkind { - /* The program has exited. The exit status is in value.integer. */ - TARGET_WAITKIND_EXITED, - - /* The program has stopped with a signal. Which signal is in value.sig. */ - TARGET_WAITKIND_STOPPED, - - /* The program has terminated with a signal. Which signal is in - value.sig. */ - TARGET_WAITKIND_SIGNALLED, - - /* The program is letting us know that it dynamically loaded something - (e.g. it called load(2) on AIX). */ - TARGET_WAITKIND_LOADED, - - /* 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. */ - TARGET_WAITKIND_SPURIOUS - }; - -/* The numbering of these signals is chosen to match traditional unix - signals (insofar as various unices use the same numbers, anyway). - It is also the numbering of the GDB remote protocol. Other remote - protocols, if they use a different numbering, should make sure to - translate appropriately. */ - -/* This is based strongly on Unix/POSIX signals for several reasons: - (1) This set of signals represents a widely-accepted attempt to - represent events of this sort in a portable fashion, (2) we want a - signal to make it from wait to child_wait to the user intact, (3) many - remote protocols use a similar encoding. However, it is - recognized that this set of signals has limitations (such as not - distinguishing between various kinds of SIGSEGV, or not - distinguishing hitting a breakpoint from finishing a single step). - So in the future we may get around this either by adding additional - signals for breakpoint, single-step, etc., or by adding signal - codes; the latter seems more in the spirit of what BSD, System V, - etc. are doing to address these issues. */ - -/* For an explanation of what each signal means, see - target_signal_to_string. */ - -enum target_signal { - /* Used some places (e.g. stop_signal) to record the concept that - there is no signal. */ - TARGET_SIGNAL_0 = 0, - TARGET_SIGNAL_FIRST = 0, - TARGET_SIGNAL_HUP = 1, - TARGET_SIGNAL_INT = 2, - TARGET_SIGNAL_QUIT = 3, - TARGET_SIGNAL_ILL = 4, - TARGET_SIGNAL_TRAP = 5, - TARGET_SIGNAL_ABRT = 6, - TARGET_SIGNAL_EMT = 7, - TARGET_SIGNAL_FPE = 8, - TARGET_SIGNAL_KILL = 9, - TARGET_SIGNAL_BUS = 10, - TARGET_SIGNAL_SEGV = 11, - TARGET_SIGNAL_SYS = 12, - TARGET_SIGNAL_PIPE = 13, - TARGET_SIGNAL_ALRM = 14, - TARGET_SIGNAL_TERM = 15, - TARGET_SIGNAL_URG = 16, - TARGET_SIGNAL_STOP = 17, - TARGET_SIGNAL_TSTP = 18, - TARGET_SIGNAL_CONT = 19, - TARGET_SIGNAL_CHLD = 20, - TARGET_SIGNAL_TTIN = 21, - TARGET_SIGNAL_TTOU = 22, - TARGET_SIGNAL_IO = 23, - TARGET_SIGNAL_XCPU = 24, - TARGET_SIGNAL_XFSZ = 25, - TARGET_SIGNAL_VTALRM = 26, - TARGET_SIGNAL_PROF = 27, - TARGET_SIGNAL_WINCH = 28, - TARGET_SIGNAL_LOST = 29, - TARGET_SIGNAL_USR1 = 30, - TARGET_SIGNAL_USR2 = 31, - TARGET_SIGNAL_PWR = 32, - /* Similar to SIGIO. Perhaps they should have the same number. */ - TARGET_SIGNAL_POLL = 33, - TARGET_SIGNAL_WIND = 34, - TARGET_SIGNAL_PHONE = 35, - TARGET_SIGNAL_WAITING = 36, - TARGET_SIGNAL_LWP = 37, - TARGET_SIGNAL_DANGER = 38, - TARGET_SIGNAL_GRANT = 39, - TARGET_SIGNAL_RETRACT = 40, - TARGET_SIGNAL_MSG = 41, - TARGET_SIGNAL_SOUND = 42, - TARGET_SIGNAL_SAK = 43, - - /* Some signal we don't know about. */ - TARGET_SIGNAL_UNKNOWN, - - /* Use whatever signal we use when one is not specifically specified - (for passing to proceed and so on). */ - TARGET_SIGNAL_DEFAULT, - - /* Last and unused enum value, for sizing arrays, etc. */ - TARGET_SIGNAL_LAST -}; - -struct target_waitstatus { - enum target_waitkind kind; - - /* Exit status or signal number. */ - union { - int integer; - enum target_signal sig; - } value; -}; - -/* Return the string for a signal. */ -extern char *target_signal_to_string PARAMS ((enum target_signal)); - -/* Return the name (SIGHUP, etc.) for a signal. */ -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. */ -/* Right now we just call (*TARGET_ACTIVITY_FUNCTION) if I/O is possible - on TARGET_ACTIVITY_FD. */ -extern int target_activity_fd; -/* Returns zero to leave the inferior alone, one to interrupt it. */ -extern int (*target_activity_function) PARAMS ((void)); - -struct target_ops -{ - char *to_shortname; /* Name this target type */ - char *to_longname; /* Name for printing */ - char *to_doc; /* Documentation. Does not include trailing - newline, and starts with a one-line descrip- - tion (probably similar to to_longname). */ - void (*to_open) PARAMS ((char *, int)); - void (*to_close) PARAMS ((int)); - void (*to_attach) PARAMS ((char *, int)); - void (*to_detach) PARAMS ((char *, int)); - void (*to_resume) PARAMS ((int, int, enum target_signal)); - int (*to_wait) PARAMS ((int, struct target_waitstatus *)); - void (*to_fetch_registers) PARAMS ((int)); - void (*to_store_registers) PARAMS ((int)); - void (*to_prepare_to_store) PARAMS ((void)); - - /* Transfer LEN bytes of memory between GDB address MYADDR and - target address MEMADDR. If WRITE, transfer them to the target, else - transfer them from the target. TARGET is the target from which we - get this function. - - Return value, N, is one of the following: - - 0 means that we can't handle this. If errno has been set, it is the - error which prevented us from doing it (FIXME: What about bfd_error?). - - positive (call it N) means that we have transferred N bytes - starting at MEMADDR. We might be able to handle more bytes - beyond this length, but no promises. - - negative (call its absolute value N) means that we cannot - transfer right at MEMADDR, but we could transfer at least - something at MEMADDR + N. */ - - int (*to_xfer_memory) PARAMS ((CORE_ADDR memaddr, char *myaddr, - int len, int write, - struct target_ops * target)); - -#if 0 - /* Enable this after 4.12. */ - - /* Search target memory. Start at STARTADDR and take LEN bytes of - target memory, and them with MASK, and compare to DATA. If they - match, set *ADDR_FOUND to the address we found it at, store the data - we found at LEN bytes starting at DATA_FOUND, and return. If - not, add INCREMENT to the search address and keep trying until - the search address is outside of the range [LORANGE,HIRANGE). - - If we don't find anything, set *ADDR_FOUND to (CORE_ADDR)0 and return. */ - void (*to_search) PARAMS ((int len, char *data, char *mask, - CORE_ADDR startaddr, int increment, - CORE_ADDR lorange, CORE_ADDR hirange, - CORE_ADDR *addr_found, char *data_found)); - -#define target_search(len, data, mask, startaddr, increment, lorange, hirange, addr_found, data_found) \ - (*current_target->to_search) (len, data, mask, startaddr, increment, \ - lorange, hirange, addr_found, data_found) -#endif /* 0 */ - - void (*to_files_info) PARAMS ((struct target_ops *)); - int (*to_insert_breakpoint) PARAMS ((CORE_ADDR, char *)); - int (*to_remove_breakpoint) PARAMS ((CORE_ADDR, char *)); - void (*to_terminal_init) PARAMS ((void)); - void (*to_terminal_inferior) PARAMS ((void)); - void (*to_terminal_ours_for_output) PARAMS ((void)); - void (*to_terminal_ours) PARAMS ((void)); - void (*to_terminal_info) PARAMS ((char *, int)); - void (*to_kill) PARAMS ((void)); - void (*to_load) PARAMS ((char *, int)); - int (*to_lookup_symbol) PARAMS ((char *, CORE_ADDR *)); - void (*to_create_inferior) PARAMS ((char *, char *, char **)); - void (*to_mourn_inferior) PARAMS ((void)); - int (*to_can_run) PARAMS ((void)); - void (*to_notice_signals) PARAMS ((int pid)); - enum strata to_stratum; - struct target_ops - *to_next; - int to_has_all_memory; - int to_has_memory; - int to_has_stack; - int to_has_registers; - int to_has_execution; - struct section_table - *to_sections; - struct section_table - *to_sections_end; - int to_magic; - /* Need sub-structure for target machine related rather than comm related? */ -}; - -/* Magic number for checking ops size. If a struct doesn't end with this - number, somebody changed the declaration but didn't change all the - places that initialize one. */ - -#define OPS_MAGIC 3840 - -/* The ops structure for our "current" target process. This should - never be NULL. If there is no target, it points to the dummy_target. */ - -extern struct target_ops *current_target; - -/* Define easy words for doing these operations on our current target. */ - -#define target_shortname (current_target->to_shortname) -#define target_longname (current_target->to_longname) - -/* The open routine takes the rest of the parameters from the command, - and (if successful) pushes a new target onto the stack. - Targets should supply this routine, if only to provide an error message. */ -#define target_open(name, from_tty) \ - (*current_target->to_open) (name, from_tty) - -/* Does whatever cleanup is required for a target that we are no longer - going to be calling. Argument says whether we are quitting gdb and - should not get hung in case of errors, or whether we want a clean - termination even if it takes a while. This routine is automatically - always called just before a routine is popped off the target stack. - Closing file descriptors and freeing memory are typical things it should - do. */ - -#define target_close(quitting) \ - (*current_target->to_close) (quitting) - -/* Attaches to a process on the target side. Arguments are as passed - to the `attach' command by the user. This routine can be called - when the target is not on the target-stack, if the target_can_run - routine returns 1; in that case, it must push itself onto the stack. - Upon exit, the target should be ready for normal operations, and - should be ready to deliver the status of the process immediately - (without waiting) to an upcoming target_wait call. */ - -#define target_attach(args, from_tty) \ - (*current_target->to_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 - in the program or it'll die when it hits one. ARGS is arguments - typed by the user (e.g. a signal to send the process). FROM_TTY - says whether to be verbose or not. */ - -extern void -target_detach PARAMS ((char *, int)); - -/* 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 - pass TARGET_SIGNAL_DEFAULT. */ - -#define target_resume(pid, step, siggnal) \ - (*current_target->to_resume) (pid, step, siggnal) - -/* Wait for process pid to do something. Pid = -1 to wait for any pid - to do something. Return pid of child, or -1 in case of error; - store status through argument pointer STATUS. Note that it is - *not* OK to return_to_top_level out of target_wait without popping - the debugging target from the stack; GDB isn't prepared to get back - to the prompt with a debugging target but without the frame cache, - stop_pc, etc., set up. */ - -#define target_wait(pid, status) \ - (*current_target->to_wait) (pid, status) - -/* Fetch register REGNO, or all regs if regno == -1. No result. */ - -#define target_fetch_registers(regno) \ - (*current_target->to_fetch_registers) (regno) - -/* Store at least register REGNO, or all regs if REGNO == -1. - It can store as many registers as it wants to, so target_prepare_to_store - must have been previously called. Calls error() if there are problems. */ - -#define target_store_registers(regs) \ - (*current_target->to_store_registers) (regs) - -/* 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. */ - -#define target_prepare_to_store() \ - (*current_target->to_prepare_to_store) () - -extern int target_read_string PARAMS ((CORE_ADDR, char **, int, int *)); - -extern int -target_read_memory PARAMS ((CORE_ADDR, char *, int)); - -extern int -target_read_memory_partial PARAMS ((CORE_ADDR, char *, int, int *)); - -extern int -target_write_memory PARAMS ((CORE_ADDR, char *, int)); - -extern int -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 int target_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, - int len, int write)); - -/* From exec.c */ - -extern void -print_section_info PARAMS ((struct target_ops *, bfd *)); - -/* Print a line about the current target. */ - -#define target_files_info() \ - (*current_target->to_files_info) (current_target) - -/* Insert a breakpoint at address ADDR in the target machine. - SAVE is a pointer to memory allocated for saving the - target contents. It is guaranteed by the caller to be long enough - to save "sizeof BREAKPOINT" bytes. Result is 0 for success, or - an errno value. */ - -#define target_insert_breakpoint(addr, save) \ - (*current_target->to_insert_breakpoint) (addr, save) - -/* Remove a breakpoint at address ADDR in the target machine. - SAVE is a pointer to the same save area - that was previously passed to target_insert_breakpoint. - Result is 0 for success, or an errno value. */ - -#define target_remove_breakpoint(addr, save) \ - (*current_target->to_remove_breakpoint) (addr, save) - -/* Initialize the terminal settings we record for the inferior, - before we actually run the inferior. */ - -#define target_terminal_init() \ - (*current_target->to_terminal_init) () - -/* Put the inferior's terminal settings into effect. - This is preparation for starting or resuming the inferior. */ - -#define target_terminal_inferior() \ - (*current_target->to_terminal_inferior) () - -/* Put some of our terminal settings into effect, - enough to get proper results from our output, - but do not change into or out of RAW mode - so that no input is discarded. - - After doing this, either terminal_ours or terminal_inferior - should be called to get back to a normal state of affairs. */ - -#define target_terminal_ours_for_output() \ - (*current_target->to_terminal_ours_for_output) () - -/* Put our terminal settings into effect. - First record the inferior's terminal settings - so they can be restored properly later. */ - -#define target_terminal_ours() \ - (*current_target->to_terminal_ours) () - -/* Print useful information about our terminal status, if such a thing - exists. */ - -#define target_terminal_info(arg, from_tty) \ - (*current_target->to_terminal_info) (arg, from_tty) - -/* Kill the inferior process. Make it go away. */ - -#define target_kill() \ - (*current_target->to_kill) () - -/* Load an executable file into the target process. This is expected to - not only bring new code into the target process, but also to update - GDB's symbol tables to match. */ - -#define target_load(arg, from_tty) \ - (*current_target->to_load) (arg, from_tty) - -/* Look up a symbol in the target's symbol table. NAME is the symbol - name. ADDRP is a CORE_ADDR * pointing to where the value of the symbol - should be returned. The result is 0 if successful, nonzero if the - symbol does not exist in the target environment. This function should - not call error() if communication with the target is interrupted, since - it is called from symbol reading, but should return nonzero, possibly - doing a complain(). */ - -#define target_lookup_symbol(name, addrp) \ - (*current_target->to_lookup_symbol) (name, addrp) - -/* 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. - ENV is the environment vector to pass. Errors reported with error(). - On VxWorks and various standalone systems, we ignore exec_file. */ - -#define target_create_inferior(exec_file, args, env) \ - (*current_target->to_create_inferior) (exec_file, args, env) - -/* The inferior process has died. Do what is right. */ - -#define target_mourn_inferior() \ - (*current_target->to_mourn_inferior) () - -/* Does target have enough data to do a run or attach command? */ - -#define target_can_run(t) \ - ((t)->to_can_run) () - -/* post process changes to signal handling in the inferior. */ - -#define target_notice_signals(pid) \ - (*current_target->to_notice_signals) (pid) - -/* Pointer to next target in the chain, e.g. a core file and an exec file. */ - -#define target_next \ - (current_target->to_next) - -/* Does the target include all of memory, or only part of it? This - determines whether we look up the target chain for other parts of - memory if this target can't satisfy a request. */ - -#define target_has_all_memory \ - (current_target->to_has_all_memory) - -/* Does the target include memory? (Dummy targets don't.) */ - -#define target_has_memory \ - (current_target->to_has_memory) - -/* Does the target have a stack? (Exec files don't, VxWorks doesn't, until - we start a process.) */ - -#define target_has_stack \ - (current_target->to_has_stack) - -/* Does the target have registers? (Exec files don't.) */ - -#define target_has_registers \ - (current_target->to_has_registers) - -/* Does the target have execution? Can we make it jump (through - hoops), or pop its stack a few times? FIXME: If this is to work that - way, it needs to check whether an inferior actually exists. - remote-udi.c and probably other targets can be the current target - when the inferior doesn't actually exist at the moment. Right now - this just tells us whether this target is *capable* of execution. */ - -#define target_has_execution \ - (current_target->to_has_execution) - -extern void target_link PARAMS ((char *, CORE_ADDR *)); - -/* Converts a process id to a string. Usually, the string just contains - `process xyz', but on some systems it may contain - `process xyz thread abc'. */ - -#ifndef target_pid_to_str -#define target_pid_to_str(PID) \ - normal_pid_to_str (PID) -extern char *normal_pid_to_str PARAMS ((int pid)); -#endif - -/* Routines for maintenance of the target structures... - - add_target: Add a target to the list of all possible targets. - - push_target: Make this target the top of the stack of currently used - targets, within its particular stratum of the stack. Result - is 0 if now atop the stack, nonzero if not on top (maybe - should warn user). - - unpush_target: Remove this from the stack of currently used targets, - no matter where it is on the list. Returns 0 if no - change, 1 if removed from stack. - - pop_target: Remove the top thing on the stack of current targets. */ - -extern void -add_target PARAMS ((struct target_ops *)); - -extern int -push_target PARAMS ((struct target_ops *)); - -extern int -unpush_target PARAMS ((struct target_ops *)); - -extern void -target_preopen PARAMS ((int)); - -extern void -pop_target PARAMS ((void)); - -/* Struct section_table maps address ranges to file sections. It is - mostly used with BFD files, but can be used without (e.g. for handling - raw disks, or files not in formats handled by BFD). */ - -struct section_table { - CORE_ADDR addr; /* Lowest address in section */ - CORE_ADDR endaddr; /* 1+highest address in section */ - - sec_ptr the_bfd_section; - - bfd *bfd; /* BFD file pointer */ -}; - -/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR. - Returns 0 if OK, 1 on error. */ - -extern int -build_section_table PARAMS ((bfd *, struct section_table **, - struct section_table **)); - -/* From mem-break.c */ - -extern int -memory_remove_breakpoint PARAMS ((CORE_ADDR, char *)); - -extern int -memory_insert_breakpoint PARAMS ((CORE_ADDR, char *)); - -/* From target.c */ - -void -noprocess PARAMS ((void)); - -void -find_default_attach PARAMS ((char *, int)); - -void -find_default_create_inferior PARAMS ((char *, char *, char **)); - -struct target_ops * -find_core_target PARAMS ((void)); - -/* Stuff that should be shared among the various remote targets. */ - -/* Debugging level. 0 is off, and non-zero values mean to print some debug - information (higher values, more information). */ -extern int remote_debug; - -/* Speed in bits per second, or -1 which means don't mess with the speed. */ -extern int baud_rate; - -/* Functions for helping to write a native target. */ - -/* This is for native targets which use a unix/POSIX-style waitstatus. */ -extern void store_waitstatus PARAMS ((struct target_waitstatus *, int)); - -/* Convert between host signal numbers and enum target_signal's. */ -extern enum target_signal target_signal_from_host PARAMS ((int)); -extern int target_signal_to_host PARAMS ((enum target_signal)); - -#endif /* !defined (TARGET_H) */ diff --git a/gnu/usr.bin/gdb/gdb/terminal.h b/gnu/usr.bin/gdb/gdb/terminal.h deleted file mode 100644 index f76fa90..0000000 --- a/gnu/usr.bin/gdb/gdb/terminal.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Terminal interface definitions for GDB, the GNU Debugger. - Copyright 1986, 1989, 1991, 1992 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 (TERMINAL_H) -#define TERMINAL_H 1 - -#if !defined(__GO32__) && !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 - ser-*.c deal with this in a much cleaner fashion; as soon as stuff - is converted to use them, can get rid of this crap. */ - -#ifdef HAVE_TERMIO - -#include - -#undef TIOCGETP -#define TIOCGETP TCGETA -#undef TIOCSETN -#define TIOCSETN TCSETA -#undef TIOCSETP -#define TIOCSETP TCSETAF -#define TERMINAL struct termio - -#else /* sgtty */ - -#include -#include -#include -#define TERMINAL struct sgttyb - -#endif /* sgtty */ -#endif /* termio or sgtty */ - -extern void new_tty PARAMS ((void)); - -/* Do we have job control? Can be assumed to always be the same within - a given run of GDB. In inflow.c. */ -extern int job_control; - -/* Set the process group of the caller to its own pid, or do nothing if - we lack job control. */ -extern int gdb_setpgid PARAMS ((void)); - -#endif /* !defined (TERMINAL_H) */ diff --git a/gnu/usr.bin/gdb/gdb/thread.c b/gnu/usr.bin/gdb/gdb/thread.c deleted file mode 100644 index c3d52c3..0000000 --- a/gnu/usr.bin/gdb/gdb/thread.c +++ /dev/null @@ -1,371 +0,0 @@ -/* Multi-process/thread control for GDB, the GNU debugger. - Copyright 1986, 1987, 1988, 1993 - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include "symtab.h" -#include "frame.h" -#include "inferior.h" -#include "environ.h" -#include "value.h" -#include "target.h" -#include "thread.h" -#include "command.h" -#include "gdbcmd.h" - -#include -#include -#include - -/*#include "lynxos-core.h"*/ - -struct thread_info -{ - struct thread_info *next; - int pid; /* Actual process id */ - int num; /* Convenient handle */ -}; - -static struct thread_info *thread_list = NULL; -static int highest_thread_num; - -static void thread_command PARAMS ((char * tidstr, int from_tty)); - -static void prune_threads PARAMS ((void)); - -static void thread_switch PARAMS ((int pid)); - -static struct thread_info * find_thread_id PARAMS ((int num)); - -void -init_thread_list () -{ - struct thread_info *tp, *tpnext; - - if (!thread_list) - return; - - for (tp = thread_list; tp; tp = tpnext) - { - tpnext = tp->next; - free (tp); - } - - thread_list = NULL; - highest_thread_num = 0; -} - -void -add_thread (pid) - int pid; -{ - struct thread_info *tp; - - tp = (struct thread_info *) xmalloc (sizeof (struct thread_info)); - - tp->pid = pid; - tp->num = ++highest_thread_num; - tp->next = thread_list; - thread_list = tp; -} - -static struct thread_info * -find_thread_id (num) - int num; -{ - struct thread_info *tp; - - for (tp = thread_list; tp; tp = tp->next) - if (tp->num == num) - return tp; - - return NULL; -} - -int -valid_thread_id (num) - int num; -{ - struct thread_info *tp; - - for (tp = thread_list; tp; tp = tp->next) - if (tp->num == num) - return 1; - - return 0; -} - -int -pid_to_thread_id (pid) - int pid; -{ - struct thread_info *tp; - - for (tp = thread_list; tp; tp = tp->next) - if (tp->pid == pid) - return tp->num; - - return 0; -} - -int -in_thread_list (pid) - int pid; -{ - struct thread_info *tp; - - for (tp = thread_list; tp; tp = tp->next) - if (tp->pid == pid) - return 1; - - return 0; /* Never heard of 'im */ -} - -static void -prune_threads () -{ - struct thread_info *tp, *tpprev; - - 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; -} - -/* Print information about currently known threads */ - -static void -info_threads_command (arg, from_tty) - char *arg; - int from_tty; -{ - struct thread_info *tp; - int current_pid = inferior_pid; - - for (tp = thread_list; tp; tp = tp->next) - { - if (target_has_execution - && kill (tp->pid, 0) == -1) - { - tp->pid = -1; /* Mark it as dead */ - continue; - } - - if (tp->pid == current_pid) - printf_filtered ("* "); - else - printf_filtered (" "); - - printf_filtered ("%d %s ", tp->num, target_pid_to_str (tp->pid)); - - thread_switch (tp->pid); - print_stack_frame (selected_frame, -1, 0); - } - - thread_switch (current_pid); - prune_threads (); -} - -/* Switch from one thread to another. */ - -static void -thread_switch (pid) - int pid; -{ - if (pid == inferior_pid) - return; - - inferior_pid = pid; - flush_cached_frames (); - registers_changed (); - stop_pc = read_pc(); - set_current_frame (create_new_frame (read_fp (), stop_pc)); - stop_frame_address = FRAME_FP (get_current_frame ()); - select_frame (get_current_frame (), 0); -} - -static void -restore_current_thread (pid) - int pid; -{ - if (pid != inferior_pid) - thread_switch (pid); -} - -/* Apply a GDB command to a list of threads. List syntax is a whitespace - seperated list of numbers, or ranges, or the keyword `all'. Ranges consist - of two numbers seperated by a hyphen. Examples: - - thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4 - thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9 - thread apply all p x/i $pc Apply x/i $pc cmd to all threads -*/ - -static void -thread_apply_all_command (cmd, from_tty) - char *cmd; - int from_tty; -{ - struct thread_info *tp; - struct cleanup *old_chain; - - if (cmd == NULL || *cmd == '\000') - error ("Please specify a command following the thread ID list"); - - old_chain = make_cleanup (restore_current_thread, 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); - } -} - -static void -thread_apply_command (tidlist, from_tty) - char *tidlist; - int from_tty; -{ - char *cmd; - char *p; - struct cleanup *old_chain; - - if (tidlist == NULL || *tidlist == '\000') - error ("Please specify a thread ID list"); - - for (cmd = tidlist; *cmd != '\000' && !isalpha(*cmd); cmd++); - - if (*cmd == '\000') - error ("Please specify a command following the thread ID list"); - - old_chain = make_cleanup (restore_current_thread, inferior_pid); - - while (tidlist < cmd) - { - struct thread_info *tp; - int start, end; - - start = strtol (tidlist, &p, 10); - if (p == tidlist) - error ("Error parsing %s", tidlist); - tidlist = p; - - while (*tidlist == ' ' || *tidlist == '\t') - tidlist++; - - if (*tidlist == '-') /* Got a range of IDs? */ - { - tidlist++; /* Skip the - */ - end = strtol (tidlist, &p, 10); - if (p == tidlist) - error ("Error parsing %s", tidlist); - tidlist = p; - - while (*tidlist == ' ' || *tidlist == '\t') - tidlist++; - } - else - end = start; - - for (; start <= end; start++) - { - tp = find_thread_id (start); - - if (!tp) - { - warning ("Unknown thread %d.", start); - continue; - } - - thread_switch (tp->pid); - printf_filtered ("\nThread %d (%s):\n", tp->num, - target_pid_to_str (inferior_pid)); - execute_command (cmd, from_tty); - } - } -} - -/* Switch to the specified thread. Will dispatch off to thread_apply_command - if prefix of arg is `apply'. */ - -static void -thread_command (tidstr, from_tty) - char *tidstr; - int from_tty; -{ - int num; - 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."); - - num = atoi (tidstr); - - tp = find_thread_id (num); - - if (!tp) - 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); - - printf_filtered ("[Switching to %s]\n", target_pid_to_str (inferior_pid)); - print_stack_frame (selected_frame, selected_frame_level, 1); -} - -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; - - add_info ("threads", info_threads_command, - "IDs of currently known threads."); - - add_prefix_cmd ("thread", class_run, thread_command, - "Use this command to switch between threads.\n\ -The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1, - &cmdlist); - - add_prefix_cmd ("apply", class_run, thread_apply_command, - "Apply a command to a list of threads.", - &thread_apply_list, "apply ", 1, &thread_cmd_list); - - add_cmd ("all", class_run, thread_apply_all_command, - "Apply a command to all threads.", - &thread_apply_list); - - add_com_alias ("t", "thread", class_run, 1); -} diff --git a/gnu/usr.bin/gdb/gdb/thread.h b/gnu/usr.bin/gdb/gdb/thread.h deleted file mode 100644 index 2ec94fc..0000000 --- a/gnu/usr.bin/gdb/gdb/thread.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Multi-process/thread control defs for GDB, the GNU debugger. - Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993 - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef THREAD_H -#define THREAD_H - -extern void init_thread_list PARAMS ((void)); - -extern void add_thread PARAMS ((int pid)); - -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)); - -#endif /* THREAD_H */ diff --git a/gnu/usr.bin/gdb/gdb/tm-i386v.h b/gnu/usr.bin/gdb/gdb/tm-i386v.h deleted file mode 100644 index 1584b82..0000000 --- a/gnu/usr.bin/gdb/gdb/tm-i386v.h +++ /dev/null @@ -1,296 +0,0 @@ -/* Macro definitions for i386, Unix System V. - Copyright 1986, 1987, 1989, 1991, 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 (TM_I386V_H) -#define TM_I386V_H 1 - -/* - * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu) - * July 1988 - */ - -#define TARGET_BYTE_ORDER LITTLE_ENDIAN - -/* turn this on when rest of gdb is ready */ -#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. - */ -#ifndef START_INFERIOR_TRAPS_EXPECTED -#define START_INFERIOR_TRAPS_EXPECTED 4 -#endif - -/* 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(frompc) {(frompc) = i386_skip_prologue((frompc));} - -extern int -i386_skip_prologue PARAMS ((int)); - -/* 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) \ - (read_memory_integer (read_register (SP_REGNUM), 4)) - -/* Stack grows downward. */ - -#define INNER_THAN < - -/* Sequence of bytes for breakpoint instruction. */ - -#define BREAKPOINT {0xcc} - -/* 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 1 -#endif - -/* Nonzero if instruction at PC is a return instruction. */ - -#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0xc3) - -/* Return 1 if P points to an invalid floating point value. - LEN is the length in bytes -- not relevant on the 386. */ - -#define INVALID_FLOAT(p, len) (0) - -/* 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 4 - -/* Number of machine registers */ - -#define NUM_REGS 16 - -/* 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", \ - } - -/* Register numbers of various important registers. - Note that some of these values are "real" register numbers, - and correspond to the general registers of the machine, - and some are "phony" register numbers which are too large - to be actual register numbers as far as the user is concerned - but do serve to get the desired values when passed to read_register. */ - -#define FP_REGNUM 5 /* Contains address of executing stack frame */ -#define SP_REGNUM 4 /* Contains address of top of stack */ - -#define PC_REGNUM 8 -#define PS_REGNUM 9 - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ -#define REGISTER_BYTES (NUM_REGS * 4) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#define REGISTER_BYTE(N) ((N)*4) - -/* Number of bytes of storage in the actual machine representation - for register N. */ - -#define REGISTER_RAW_SIZE(N) (4) - -/* Number of bytes of storage in the program's representation - for register N. */ - -#define REGISTER_VIRTUAL_SIZE(N) (4) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 4 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#define MAX_REGISTER_VIRTUAL_SIZE 4 - -/* Return the GDB type object for the "standard" data type - of data in register N. */ -/* Perhaps si and di should go here, but potentially they could be - used for things other than address. */ -#define REGISTER_VIRTUAL_TYPE(N) \ - ((N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM ? \ - lookup_pointer_type (builtin_type_void) : builtin_type_int) - -/* Store the address of the place in which to copy the structure the - 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)); } - -/* 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) \ - memcpy ((VALBUF), (REGBUF), TYPE_LENGTH (TYPE)) - -/* Write into appropriate registers a function return value - of type TYPE, given in virtual format. */ - -#define STORE_RETURN_VALUE(TYPE,VALBUF) \ - write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE)) - -/* 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). */ - -#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF)) - - -/* 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) \ - (!inside_entry_file ((thisframe)->pc) ? \ - read_memory_integer ((thisframe)->frame, 4) :\ - 0) - -/* 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. */ -#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \ - (FRAMELESS) = frameless_look_for_prologue(FI) - -#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4)) - -#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame) - -#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame) - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ - -#define FRAME_NUM_ARGS(numargs, fi) (numargs) = -1 - -#ifdef __STDC__ /* Forward decl's for prototypes */ -struct frame_info; -struct frame_saved_regs; -#endif - -extern int -i386_frame_num_args PARAMS ((struct frame_info *)); - -/* Return number of bytes at start of arglist that are not really args. */ - -#define FRAME_ARGS_SKIP 8 - -/* 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. */ - -#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ -{ i386_frame_find_saved_regs ((frame_info), &(frame_saved_regs)); } - -extern void -i386_frame_find_saved_regs PARAMS ((struct frame_info *, - struct frame_saved_regs *)); - - -/* Things needed for making the inferior call functions. */ - -/* Push an empty stack frame, to record the current PC, etc. */ - -#define PUSH_DUMMY_FRAME { i386_push_dummy_frame (); } - -extern void -i386_push_dummy_frame PARAMS ((void)); - -/* Discard from the stack the innermost frame, restoring all registers. */ - -#define POP_FRAME { i386_pop_frame (); } - -extern void -i386_pop_frame PARAMS ((void)); - -/* this is - * call 11223344 (32 bit relative) - * int3 - */ - -#define CALL_DUMMY { 0x223344e8, 0xcc11 } - -#define CALL_DUMMY_LENGTH 8 - -#define CALL_DUMMY_START_OFFSET 0 /* Start execution at beginning of dummy */ - -#define CALL_DUMMY_BREAKPOINT_OFFSET 5 - -/* Insert the specified number of args and function address - into a call sequence of the above form stored at DUMMYNAME. */ - -#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \ -{ \ - int from, to, delta, loc; \ - loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH); \ - from = loc + 5; \ - to = (int)(fun); \ - delta = to - from; \ - *((char *)(dummyname) + 1) = (delta & 0xff); \ - *((char *)(dummyname) + 2) = ((delta >> 8) & 0xff); \ - *((char *)(dummyname) + 3) = ((delta >> 16) & 0xff); \ - *((char *)(dummyname) + 4) = ((delta >> 24) & 0xff); \ -} - -extern void -print_387_control_word PARAMS ((unsigned int)); - -extern void -print_387_status_word PARAMS ((unsigned int)); - -/* Offset from SP to first arg on stack at first instruction of a function */ - -#define SP_ARG0 (1 * 4) - -#endif /* !defined (TM_I386V_H) */ diff --git a/gnu/usr.bin/gdb/gdb/tm.h b/gnu/usr.bin/gdb/gdb/tm.h index f775da9..6b1dc06 100644 --- a/gnu/usr.bin/gdb/gdb/tm.h +++ b/gnu/usr.bin/gdb/gdb/tm.h @@ -1,5 +1,5 @@ -/* Macro definitions for i386 running under BSD Unix. - Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. +/* Macro definitions for x86 running under FreeBSD Unix. + Copyright 1996 Free Software Foundation, Inc. This file is part of GDB. @@ -15,43 +15,33 @@ 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _FREEBSD_TM_H_ -#define _FREEBSD_TM_H_ -/* Override number of expected traps from sysv. */ -#define START_INFERIOR_TRAPS_EXPECTED 2 +#ifndef TM_FBSD_H +#define TM_FBSD_H 1 -/* Most definitions from sysv could be used. */ -#include "tm-i386v.h" +#include "i386/tm-i386bsd.h" -/* 386BSD cannot handle the segment registers. */ -/* BSDI can't handle them either. */ -/* FreeBSD cannot handle %fs or %gs. */ #undef NUM_REGS -#ifdef __FreeBSD__ #define NUM_REGS 14 -#else -#define NUM_REGS 10 -#endif -/* 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 +extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *)); -/* The following redefines make backtracing through sigtramp work. - They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp - from the sigcontext structure which is pushed by the kernel on the - user stack, along with a pointer to it. */ +#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv) + +extern void i386_float_info PARAMS ((void)); + +#define FLOAT_INFO i386_float_info () + +#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) STREQ (name, "_DYNAMIC") /* FRAME_CHAIN takes a frame's nominal address and produces the frame's chain-pointer. In the case of the i386, the frame's nominal address is the address of a 4-byte word containing the calling frame's address. */ -#undef FRAME_CHAIN + extern CORE_ADDR fbsd_kern_frame_chain (struct frame_info *); +#undef FRAME_CHAIN #define FRAME_CHAIN(thisframe) \ (kernel_debugging ? fbsd_kern_frame_chain(thisframe) : \ ((thisframe)->signal_handler_caller \ @@ -60,25 +50,10 @@ extern CORE_ADDR fbsd_kern_frame_chain (struct frame_info *); ? read_memory_integer ((thisframe)->frame, 4) \ : 0))) -/* 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. */ -#undef FRAMELESS_FUNCTION_INVOCATION -#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \ - do { \ - if ((FI)->signal_handler_caller) \ - (FRAMELESS) = 0; \ - else \ - (FRAMELESS) = frameless_look_for_prologue(FI); \ - } while (0) - /* Saved Pc. Get it from sigcontext if within sigtramp. */ -/* Offset to saved PC in sigcontext, from . */ -#define SIGCONTEXT_PC_OFFSET 20 - -#undef FRAME_SAVED_PC extern CORE_ADDR fbsd_kern_frame_saved_pc (struct frame_info *); +#undef FRAME_SAVED_PC #define FRAME_SAVED_PC(FRAME) \ (kernel_debugging ? fbsd_kern_frame_saved_pc(FRAME) : \ (((FRAME)->signal_handler_caller \ @@ -86,9 +61,4 @@ extern CORE_ADDR fbsd_kern_frame_saved_pc (struct frame_info *); : read_memory_integer ((FRAME)->frame + 4, 4)) \ )) -#undef SETUP_ARBITRARY_FRAME -#include "frame.h" -extern FRAME setup_arbitrary_frame (); -#define SETUP_ARBITRARY_FRAME setup_arbitrary_frame - -#endif /* _FREEBSD_TM_H_ */ +#endif /* TM_FBSD_H */ diff --git a/gnu/usr.bin/gdb/gdb/top.c b/gnu/usr.bin/gdb/gdb/top.c deleted file mode 100644 index f90f141..0000000 --- a/gnu/usr.bin/gdb/gdb/top.c +++ /dev/null @@ -1,2494 +0,0 @@ -/* Top level stuff for GDB, the GNU debugger. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 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. */ - -#include "defs.h" -#include "gdbcmd.h" -#include "call-cmds.h" -#include "symtab.h" -#include "inferior.h" -#include "signals.h" -#include "target.h" -#include "breakpoint.h" -#include "gdbtypes.h" -#include "expression.h" -#include "language.h" -#include "terminal.h" /* For job_control. */ -#include "annotate.h" -#include -#include "top.h" - -/* readline include files */ -#include "readline.h" -#include "history.h" - -/* readline defines this. */ -#undef savestring - -#include -#ifdef USG -/* What is this for? X_OK? */ -#include -#endif - -#include -#ifndef NO_SYS_FILE -#include -#endif -#include -#include -#include - -/* Prototypes for local functions */ - -static char * -symbol_completion_function PARAMS ((char *, int)); - -static void -command_loop_marker PARAMS ((int)); - -static void -init_main PARAMS ((void)); - -static void -init_cmd_lists PARAMS ((void)); - -static void -float_handler PARAMS ((int)); - -static void -init_signals PARAMS ((void)); - -static void -set_verbose PARAMS ((char *, int, struct cmd_list_element *)); - -static void -show_history PARAMS ((char *, int)); - -static void -set_history PARAMS ((char *, int)); - -static void -set_history_size_command PARAMS ((char *, int, struct cmd_list_element *)); - -static void -show_commands PARAMS ((char *, int)); - -static void -echo_command PARAMS ((char *, int)); - -static void -pwd_command PARAMS ((char *, int)); - -static void -show_version PARAMS ((char *, int)); - -static void -document_command PARAMS ((char *, int)); - -static void -define_command PARAMS ((char *, int)); - -static void -validate_comname PARAMS ((char *)); - -static void -help_command PARAMS ((char *, int)); - -static void -show_command PARAMS ((char *, int)); - -static void -info_command PARAMS ((char *, int)); - -static void -complete_command PARAMS ((char *, int)); - -static void -do_nothing PARAMS ((int)); - -static int -quit_cover PARAMS ((char *)); - -static void -disconnect PARAMS ((int)); - -static void -source_cleanup PARAMS ((FILE *)); - -/* 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 - -/* Initialization file name for gdb. This is overridden in some configs. */ - -#ifndef GDBINIT_FILENAME -#define GDBINIT_FILENAME ".gdbinit" -#endif -char gdbinit[] = GDBINIT_FILENAME; -int inhibit_gdbinit = 0; - -/* Version number of GDB, as a string. */ - -extern char *version; - -/* Canonical host name as a string. */ - -extern char *host_name; - -/* Canonical target name as a string. */ - -extern char *target_name; - -extern char lang_frame_mismatch_warn[]; /* language.c */ - -/* Flag for whether we want all the "from_tty" gubbish printed. */ - -int caution = 1; /* Default is yes, sigh. */ - -/* - * Define all cmd_list_element's - */ - -/* Chain containing all defined commands. */ - -struct cmd_list_element *cmdlist; - -/* Chain containing all defined info subcommands. */ - -struct cmd_list_element *infolist; - -/* Chain containing all defined enable subcommands. */ - -struct cmd_list_element *enablelist; - -/* Chain containing all defined disable subcommands. */ - -struct cmd_list_element *disablelist; - -/* Chain containing all defined delete subcommands. */ - -struct cmd_list_element *deletelist; - -/* Chain containing all defined "enable breakpoint" subcommands. */ - -struct cmd_list_element *enablebreaklist; - -/* Chain containing all defined set subcommands */ - -struct cmd_list_element *setlist; - -/* Chain containing all defined unset subcommands */ - -struct cmd_list_element *unsetlist; - -/* Chain containing all defined show subcommands. */ - -struct cmd_list_element *showlist; - -/* Chain containing all defined \"set history\". */ - -struct cmd_list_element *sethistlist; - -/* Chain containing all defined \"show history\". */ - -struct cmd_list_element *showhistlist; - -/* Chain containing all defined \"unset history\". */ - -struct cmd_list_element *unsethistlist; - -/* Chain containing all defined maintenance subcommands. */ - -#if MAINTENANCE_CMDS -struct cmd_list_element *maintenancelist; -#endif - -/* Chain containing all defined "maintenance info" subcommands. */ - -#if MAINTENANCE_CMDS -struct cmd_list_element *maintenanceinfolist; -#endif - -/* Chain containing all defined "maintenance print" subcommands. */ - -#if MAINTENANCE_CMDS -struct cmd_list_element *maintenanceprintlist; -#endif - -struct cmd_list_element *setprintlist; - -struct cmd_list_element *showprintlist; - -struct cmd_list_element *setchecklist; - -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. */ - -FILE *instream; - -/* Current working directory. */ - -char *current_directory; - -/* The directory name is actually stored here (usually). */ -char gdb_dirbuf[1024]; - -/* Function to call before reading a command, if nonzero. - The function receives two args: an input stream, - and a prompt string. */ - -void (*window_hook) PARAMS ((FILE *, char *)); - -int epoch_interface; -int xgdb_verbose; - -/* gdb prints this when reading a command interactively */ -static char *prompt; - -/* Buffer used for reading command lines, and the size - allocated for it so far. */ - -char *line; -int linesize = 100; - -/* Nonzero if the current command is modified by "server ". This - affects things like recording into the command history, comamnds - repeating on RETURN, etc. This is so a user interface (emacs, GUI, - whatever) can issue its own commands and also send along commands - from the user, and have the user not notice that the user interface - is issuing commands too. */ -int server_command; - -/* Baud rate specified for talking to serial target systems. Default - is left as -1, so targets can choose their own defaults. */ -/* FIXME: This means that "show remotebaud" and gr_files_info can print -1 - or (unsigned int)-1. This is a Bad User Interface. */ - -int baud_rate = -1; - -/* Non-zero tells remote* modules to output debugging info. */ - -int remote_debug = 0; - -/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */ - -#ifndef STOP_SIGNAL -#ifdef SIGTSTP -#define STOP_SIGNAL SIGTSTP -static void stop_sig PARAMS ((int)); -#endif -#endif - -/* Some System V have job control but not sigsetmask(). */ -#if !defined (HAVE_SIGSETMASK) -#if !defined (USG) -#define HAVE_SIGSETMASK 1 -#else -#define HAVE_SIGSETMASK 0 -#endif -#endif - -#if 0 == (HAVE_SIGSETMASK) -#define sigsetmask(n) -#endif - -/* Where to go for return_to_top_level (RETURN_ERROR). */ -jmp_buf error_return; -/* Where to go for return_to_top_level (RETURN_QUIT). */ -jmp_buf quit_return; - -#ifdef KERNEL_DEBUG -/* Non-zero means we are debugging a kernel core file */ -int kernel_debugging = 0; -int kernel_writablecore = 0; -#endif - -/* Return for reason REASON. This generally gets back to the command - loop, but can be caught via catch_errors. */ - -NORETURN void -return_to_top_level (reason) - enum return_reason reason; -{ - quit_flag = 0; - immediate_quit = 0; - - /* Perhaps it would be cleaner to do this via the cleanup chain (not sure - I can think of a reason why that is vital, though). */ - bpstat_clear_actions(stop_bpstat); /* Clear queued breakpoint commands */ - - disable_current_display (); - do_cleanups (ALL_CLEANUPS); - - if (annotation_level > 1) - switch (reason) - { - case RETURN_QUIT: - annotate_quit (); - break; - case RETURN_ERROR: - annotate_error (); - break; - } - - (NORETURN void) longjmp - (reason == RETURN_ERROR ? error_return : quit_return, 1); -} - -/* Call FUNC with arg ARGS, catching any errors. If there is no - error, return the value returned by FUNC. If there is an error, - print ERRSTRING, print the specific error message, then return - zero. - - 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. - - MASK specifies what to catch; it is normally set to - RETURN_MASK_ALL, if for no other reason than that the code which - calls catch_errors might not be set up to deal with a quit which - isn't caught. But if the code can deal with it, it generally - should be RETURN_MASK_ERROR, unless for some reason it is more - useful to abort only the portion of the operation inside the - catch_errors. Note that quit should return to the command line - fairly quickly, even if some further processing is being done. */ - -int -catch_errors (func, args, errstring, mask) - int (*func) PARAMS ((char *)); - PTR args; - char *errstring; - return_mask mask; -{ - jmp_buf saved_error; - jmp_buf saved_quit; - jmp_buf tmp_jmp; - int val; - struct cleanup *saved_cleanup_chain; - char *saved_error_pre_print; - - saved_cleanup_chain = save_cleanups (); - saved_error_pre_print = error_pre_print; - - if (mask & RETURN_MASK_ERROR) - memcpy ((char *)saved_error, (char *)error_return, sizeof (jmp_buf)); - if (mask & RETURN_MASK_QUIT) - memcpy (saved_quit, quit_return, sizeof (jmp_buf)); - error_pre_print = errstring; - - if (setjmp (tmp_jmp) == 0) - { - if (mask & RETURN_MASK_ERROR) - memcpy (error_return, tmp_jmp, sizeof (jmp_buf)); - if (mask & RETURN_MASK_QUIT) - memcpy (quit_return, tmp_jmp, sizeof (jmp_buf)); - val = (*func) (args); - } - else - val = 0; - - restore_cleanups (saved_cleanup_chain); - - error_pre_print = saved_error_pre_print; - if (mask & RETURN_MASK_ERROR) - memcpy (error_return, saved_error, sizeof (jmp_buf)); - if (mask & RETURN_MASK_QUIT) - memcpy (quit_return, saved_quit, sizeof (jmp_buf)); - return val; -} - -/* Handler for SIGHUP. */ - -static void -disconnect (signo) -int signo; -{ - catch_errors (quit_cover, NULL, - "Could not kill the program being debugged", RETURN_MASK_ALL); - signal (SIGHUP, SIG_DFL); - kill (getpid (), SIGHUP); -} - -/* Just a little helper function for disconnect(). */ - -static int -quit_cover (s) -char *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; -} - -/* Line number we are currently in in a file which is being sourced. */ -static int source_line_number; - -/* Name of the file we are sourcing. */ -static char *source_file_name; - -/* Buffer containing the error_pre_print used by the source stuff. - Malloc'd. */ -static char *source_error; -static int source_error_allocated; - -/* Something to glom on to the start of error_pre_print if source_file_name - is set. */ -static char *source_pre_error; - -/* Clean up on error during a "source" command (or execution of a - user-defined command). */ - -static void -source_cleanup (stream) - FILE *stream; -{ - /* Restore the previous input stream. */ - instream = stream; -} - -/* Read commands from STREAM. */ -void -read_command_file (stream) - FILE *stream; -{ - struct cleanup *cleanups; - - cleanups = make_cleanup (source_cleanup, instream); - instream = stream; - command_loop (); - do_cleanups (cleanups); -} - -extern void init_proc (); - -void -gdb_init () -{ - /* Run the init function of each source file */ - - getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); - current_directory = gdb_dirbuf; - - init_cmd_lists (); /* This needs to be done first */ - initialize_all_files (); - init_main (); /* But that omits this file! Do it now */ - init_signals (); - - init_proc (); - - /* We need a default language for parsing expressions, so simple things like - "set width 0" won't fail if no language is explicitly set in a config file - or implicitly set by reading an executable during startup. */ - set_language (language_c); - expected_language = current_language; /* don't warn about the change. */ -} - -void -execute_user_command (c, args) - struct cmd_list_element *c; - char *args; -{ - register struct command_line *cmdlines; - struct cleanup *old_chain; - - if (args) - error ("User-defined commands cannot take arguments."); - - cmdlines = c->user_commands; - if (cmdlines == 0) - /* Null command */ - return; - - /* Set the instream to 0, indicating execution of a - user-defined function. */ - old_chain = make_cleanup (source_cleanup, instream); - instream = (FILE *) 0; - while (cmdlines) - { - execute_command (cmdlines->line, 0); - cmdlines = cmdlines->next; - } - do_cleanups (old_chain); -} - -/* Execute the line P as a command. - Pass FROM_TTY as second argument to the defining function. */ - -void -execute_command (p, from_tty) - char *p; - int from_tty; -{ - register struct cmd_list_element *c; - register enum language flang; - static int warned = 0; - - free_all_values (); - - /* This can happen when command_line_input hits end of file. */ - if (p == NULL) - return; - - while (*p == ' ' || *p == '\t') p++; - if (*p) - { - char *arg; - - c = lookup_cmd (&p, cmdlist, "", 0, 1); - /* Pass null arg rather than an empty one. */ - arg = *p ? p : 0; - - /* If this command has been hooked, run the hook first. */ - if (c->hook) - execute_user_command (c->hook, (char *)0); - - if (c->class == class_user) - execute_user_command (c, arg); - else if (c->type == set_cmd || c->type == show_cmd) - do_setshow_command (arg, from_tty & caution, c); - else if (c->function.cfunc == NO_FUNCTION) - error ("That is not a command, just a help topic."); - else - (*c->function.cfunc) (arg, from_tty & caution); - } - - /* Tell the user if the language has changed (except first time). */ - if (current_language != expected_language) - { - if (language_mode == language_mode_auto) { - language_info (1); /* Print what changed. */ - } - warned = 0; - } - - /* Warn the user if the working language does not match the - language of the current frame. Only warn the user if we are - actually running the program, i.e. there is a stack. */ - /* FIXME: This should be cacheing the frame and only running when - the frame changes. */ - if (target_has_stack) - { - flang = get_frame_language (); - if (!warned - && flang != language_unknown - && flang != current_language->la_language) - { - printf_filtered ("%s\n", lang_frame_mismatch_warn); - warned = 1; - } - } -} - -/* ARGSUSED */ -static void -command_loop_marker (foo) - int foo; -{ -} - -/* Read commands from `instream' and execute them - until end of file or error reading instream. */ -void -command_loop () -{ - struct cleanup *old_chain; - char *command; - int stdin_is_tty = ISATTY (stdin); - - while (!feof (instream)) - { - 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); - command = command_line_input (instream == stdin ? prompt : (char *) NULL, - instream == stdin, "prompt"); - if (command == 0) - return; - execute_command (command, instream == stdin); - /* Do any commands attached to breakpoint we stopped at. */ - bpstat_do_actions (&stop_bpstat); - do_cleanups (old_chain); - } -} - -/* Commands call this if they do not want to be repeated by null lines. */ - -void -dont_repeat () -{ - if (server_command) - return; - - /* If we aren't reading from standard input, we are saving the last - thing read from stdin in line and don't want to delete it. Null lines - won't repeat here in any case. */ - if (instream == stdin) - *line = 0; -} - -/* Read a line from the stream "instream" without command line editing. - - It prints PRROMPT once at the start. - Action is compatible with "readline", e.g. space for the result is - malloc'd and should be freed by the caller. - - A NULL return means end of file. */ -char * -gdb_readline (prrompt) - char *prrompt; -{ - int c; - char *result; - int input_index = 0; - int result_size = 80; - - if (prrompt) - { - /* Don't use a _filtered function here. It causes the assumed - character position to be off, since the newline we read from - the user is not accounted for. */ - fputs_unfiltered (prrompt, gdb_stdout); - gdb_flush (gdb_stdout); - } - - result = (char *) xmalloc (result_size); - - while (1) - { - /* Read from stdin if we are executing a user defined command. - This is the right thing for prompt_for_continue, at least. */ - c = fgetc (instream ? instream : stdin); - - if (c == EOF) - { - if (input_index > 0) - /* The last line does not end with a newline. Return it, and - if we are called again fgetc will still return EOF and - we'll return NULL then. */ - break; - free (result); - return NULL; - } - - if (c == '\n') - break; - - result[input_index++] = c; - while (input_index >= result_size) - { - result_size *= 2; - result = (char *) xrealloc (result, result_size); - } - } - - result[input_index++] = '\0'; - return result; -} - -/* Variables which control command line editing and history - substitution. These variables are given default values at the end - of this file. */ -static int command_editing_p; -static int history_expansion_p; -static int write_history_p; -static int history_size; -static char *history_filename; - -/* readline uses the word breaks for two things: - (1) In figuring out where to point the TEXT parameter to the - rl_completion_entry_function. Since we don't use TEXT for much, - it doesn't matter a lot what the word breaks are for this purpose, but - it does affect how much stuff M-? lists. - (2) If one of the matches contains a word break character, readline - will quote it. That's why we switch between - gdb_completer_word_break_characters and - gdb_completer_command_word_break_characters. I'm not sure when - we need this behavior (perhaps for funky characters in C++ symbols?). */ - -/* Variables which are necessary for fancy command line editing. */ -char *gdb_completer_word_break_characters = - " \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-"; - -/* When completing on command names, we remove '-' from the list of - word break characters, since we use it in command names. If the - readline library sees one in any of the current completion strings, - it thinks that the string needs to be quoted and automatically supplies - a leading quote. */ -char *gdb_completer_command_word_break_characters = - " \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,"; - -/* Characters that can be used to quote completion strings. Note that we - can't include '"' because the gdb C parser treats such quoted sequences - as strings. */ -char *gdb_completer_quote_characters = - "'"; - -/* Functions that are used as part of the fancy command line editing. */ - -/* This can be used for functions which don't want to complete on symbols - but don't want to complete on anything else either. */ -/* ARGSUSED */ -char ** -noop_completer (text, prefix) - char *text; - char *prefix; -{ - return NULL; -} - -/* Complete on filenames. */ -char ** -filename_completer (text, word) - char *text; - char *word; -{ - /* From readline. */ - extern char *filename_completion_function (); - int subsequent_name; - char **return_val; - int return_val_used; - int return_val_alloced; - - return_val_used = 0; - /* Small for testing. */ - return_val_alloced = 1; - return_val = (char **) xmalloc (return_val_alloced * sizeof (char *)); - - subsequent_name = 0; - while (1) - { - char *p; - p = filename_completion_function (text, subsequent_name); - if (return_val_used >= return_val_alloced) - { - return_val_alloced *= 2; - return_val = - (char **) xrealloc (return_val, - return_val_alloced * sizeof (char *)); - } - if (p == NULL) - { - return_val[return_val_used++] = p; - break; - } - /* Like emacs, don't complete on old versions. Especially useful - in the "source" command. */ - if (p[strlen (p) - 1] == '~') - continue; - - { - char *q; - if (word == text) - /* Return exactly p. */ - return_val[return_val_used++] = p; - else if (word > text) - { - /* Return some portion of p. */ - q = xmalloc (strlen (p) + 5); - strcpy (q, p + (word - text)); - return_val[return_val_used++] = q; - free (p); - } - else - { - /* Return some of TEXT plus p. */ - q = xmalloc (strlen (p) + (text - word) + 5); - strncpy (q, word, text - word); - q[text - word] = '\0'; - strcat (q, p); - return_val[return_val_used++] = q; - free (p); - } - } - subsequent_name = 1; - } -#if 0 - /* There is no way to do this just long enough to affect quote inserting - without also affecting the next completion. This should be fixed in - readline. FIXME. */ - /* Insure that readline does the right thing - with respect to inserting quotes. */ - rl_completer_word_break_characters = ""; -#endif - return return_val; -} - -/* Here are some useful test cases for completion. FIXME: These should - be put in the test suite. They should be tested with both M-? and TAB. - - "show output-" "radix" - "show output" "-radix" - "p" ambiguous (commands starting with p--path, print, printf, etc.) - "p " ambiguous (all symbols) - "info t foo" no completions - "info t " no completions - "info t" ambiguous ("info target", "info terminal", etc.) - "info ajksdlfk" no completions - "info ajksdlfk " no completions - "info" " " - "info " ambiguous (all info commands) - "p \"a" no completions (string constant) - "p 'a" ambiguous (all symbols starting with a) - "p b-a" ambiguous (all symbols starting with a) - "p b-" ambiguous (all symbols) - "file Make" "file" (word break hard to screw up here) - "file ../gdb.stabs/we" "ird" (needs to not break word at slash) - */ - -/* Generate completions one by one for the completer. Each time we are - called return another potential completion to the caller. The function - is misnamed; it just completes on commands or passes the buck to the - command's completer function; the stuff specific to symbol completion - is in make_symbol_completion_list. - - TEXT is readline's idea of the "word" we are looking at; we don't really - like readline's ideas about word breaking so we ignore it. - - MATCHES is the number of matches that have currently been collected from - calling this completion function. When zero, then we need to initialize, - otherwise the initialization has already taken place and we can just - return the next potential completion string. - - Returns NULL if there are no more completions, else a pointer to a string - which is a possible completion. - - RL_LINE_BUFFER is available to be looked at; it contains the entire text - of the line. RL_POINT is the offset in that line of the cursor. You - should pretend that the line ends at RL_POINT. */ - -static char * -symbol_completion_function (text, matches) - char *text; - int matches; -{ - static char **list = (char **)NULL; /* Cache of completions */ - static int index; /* Next cached completion */ - char *output = NULL; - char *tmp_command, *p; - /* Pointer within tmp_command which corresponds to text. */ - char *word; - struct cmd_list_element *c, *result_list; - - if (matches == 0) - { - /* The caller is beginning to accumulate a new set of completions, so - we need to find all of them now, and cache them for returning one at - a time on future calls. */ - - if (list) - { - /* Free the storage used by LIST, but not by the strings inside. - This is because rl_complete_internal () frees the strings. */ - free ((PTR)list); - } - list = 0; - index = 0; - - /* Choose the default set of word break characters to break completions. - If we later find out that we are doing completions on command strings - (as opposed to strings supplied by the individual command completer - functions, which can be any string) then we will switch to the - special word break set for command strings, which leaves out the - '-' character used in some commands. */ - - rl_completer_word_break_characters = - gdb_completer_word_break_characters; - - /* Decide whether to complete on a list of gdb commands or on symbols. */ - tmp_command = (char *) alloca (rl_point + 1); - p = tmp_command; - - strncpy (tmp_command, rl_line_buffer, rl_point); - tmp_command[rl_point] = '\0'; - /* Since text always contains some number of characters leading up - to rl_point, we can find the equivalent position in tmp_command - by subtracting that many characters from the end of tmp_command. */ - word = tmp_command + rl_point - strlen (text); - - if (rl_point == 0) - { - /* An empty line we want to consider ambiguous; that is, it - could be any command. */ - c = (struct cmd_list_element *) -1; - result_list = 0; - } - else - { - c = lookup_cmd_1 (&p, cmdlist, &result_list, 1); - } - - /* Move p up to the next interesting thing. */ - while (*p == ' ' || *p == '\t') - { - p++; - } - - if (!c) - { - /* It is an unrecognized command. So there are no - possible completions. */ - list = NULL; - } - else if (c == (struct cmd_list_element *) -1) - { - char *q; - - /* lookup_cmd_1 advances p up to the first ambiguous thing, but - doesn't advance over that thing itself. Do so now. */ - q = p; - while (*q && (isalnum (*q) || *q == '-' || *q == '_')) - ++q; - if (q != tmp_command + rl_point) - { - /* There is something beyond the ambiguous - command, so there are no possible completions. For - example, "info t " or "info t foo" does not complete - to anything, because "info t" can be "info target" or - "info terminal". */ - list = NULL; - } - else - { - /* We're trying to complete on the command which was ambiguous. - This we can deal with. */ - if (result_list) - { - list = complete_on_cmdlist (*result_list->prefixlist, p, - word); - } - else - { - list = complete_on_cmdlist (cmdlist, p, word); - } - /* Insure that readline does the right thing with respect to - inserting quotes. */ - rl_completer_word_break_characters = - gdb_completer_command_word_break_characters; - } - } - else - { - /* We've recognized a full command. */ - - if (p == tmp_command + rl_point) - { - /* There is no non-whitespace in the line beyond the command. */ - - if (p[-1] == ' ' || p[-1] == '\t') - { - /* The command is followed by whitespace; we need to complete - on whatever comes after command. */ - if (c->prefixlist) - { - /* It is a prefix command; what comes after it is - a subcommand (e.g. "info "). */ - list = complete_on_cmdlist (*c->prefixlist, p, word); - - /* Insure that readline does the right thing - with respect to inserting quotes. */ - rl_completer_word_break_characters = - gdb_completer_command_word_break_characters; - } - else - { - /* It is a normal command; what comes after it is - completed by the command's completer function. */ - list = (*c->completer) (p, word); - } - } - else - { - /* The command is not followed by whitespace; we need to - complete on the command itself. e.g. "p" which is a - command itself but also can complete to "print", "ptype" - etc. */ - char *q; - - /* Find the command we are completing on. */ - q = p; - while (q > tmp_command) - { - if (isalnum (q[-1]) || q[-1] == '-' || q[-1] == '_') - --q; - else - break; - } - - list = complete_on_cmdlist (result_list, q, word); - - /* Insure that readline does the right thing - with respect to inserting quotes. */ - rl_completer_word_break_characters = - gdb_completer_command_word_break_characters; - } - } - else - { - /* There is non-whitespace beyond the command. */ - - if (c->prefixlist && !c->allow_unknown) - { - /* It is an unrecognized subcommand of a prefix command, - e.g. "info adsfkdj". */ - list = NULL; - } - else - { - /* It is a normal command. */ - list = (*c->completer) (p, word); - } - } - } - } - - /* If we found a list of potential completions during initialization then - dole them out one at a time. The vector of completions is NULL - terminated, so after returning the last one, return NULL (and continue - to do so) each time we are called after that, until a new list is - available. */ - - if (list) - { - output = list[index]; - if (output) - { - index++; - } - } - -#if 0 - /* Can't do this because readline hasn't yet checked the word breaks - for figuring out whether to insert a quote. */ - if (output == NULL) - /* Make sure the word break characters are set back to normal for the - next time that readline tries to complete something. */ - rl_completer_word_break_characters = - gdb_completer_word_break_characters; -#endif - - return (output); -} - -/* Skip over a possibly quoted word (as defined by the quote characters - and word break characters the completer uses). Returns pointer to the - location after the "word". */ - -char * -skip_quoted (str) - char *str; -{ - char quote_char = '\0'; - char *scan; - - for (scan = str; *scan != '\0'; scan++) - { - if (quote_char != '\0') - { - /* Ignore everything until the matching close quote char */ - if (*scan == quote_char) - { - /* Found matching close quote. */ - scan++; - break; - } - } - else if (strchr (gdb_completer_quote_characters, *scan)) - { - /* Found start of a quoted string. */ - quote_char = *scan; - } - else if (strchr (gdb_completer_word_break_characters, *scan)) - { - break; - } - } - return (scan); -} - - -#ifdef STOP_SIGNAL -static void -stop_sig (signo) -int signo; -{ -#if STOP_SIGNAL == SIGTSTP - signal (SIGTSTP, SIG_DFL); - sigsetmask (0); - kill (getpid (), SIGTSTP); - signal (SIGTSTP, stop_sig); -#else - signal (STOP_SIGNAL, stop_sig); -#endif - printf_unfiltered ("%s", prompt); - gdb_flush (gdb_stdout); - - /* Forget about any previous command -- null line now will do nothing. */ - dont_repeat (); -} -#endif /* STOP_SIGNAL */ - -/* Initialize signal handlers. */ -static void -do_nothing (signo) -int signo; -{ -} - -static void -init_signals () -{ - signal (SIGINT, request_quit); - - /* If we initialize SIGQUIT to SIG_IGN, then the SIG_IGN will get - passed to the inferior, which we don't want. It would be - possible to do a "signal (SIGQUIT, SIG_DFL)" after we fork, but - on BSD4.3 systems using vfork, that can affect the - GDB process as well as the inferior (the signal handling tables - might be in memory, shared between the two). Since we establish - a handler for SIGQUIT, when we call exec it will set the signal - to SIG_DFL for us. */ - signal (SIGQUIT, do_nothing); - if (signal (SIGHUP, do_nothing) != SIG_IGN) - signal (SIGHUP, disconnect); - signal (SIGFPE, float_handler); - -#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER) - signal (SIGWINCH, SIGWINCH_HANDLER); -#endif -} - -/* Read one line from the command input stream `instream' - into the local static buffer `linebuffer' (whose current length - is `linelength'). - The buffer is made bigger as necessary. - Returns the address of the start of the line. - - NULL is returned for end of file. - - *If* the instream == stdin & stdin is a terminal, the line read - is copied into the file line saver (global var char *line, - length linesize) so that it can be duplicated. - - This routine either uses fancy command line editing or - simple input as the user has requested. */ - -char * -command_line_input (prrompt, repeat, annotation_suffix) - char *prrompt; - int repeat; - char *annotation_suffix; -{ - static char *linebuffer = 0; - static unsigned linelength = 0; - register char *p; - char *p1; - char *rl; - char *local_prompt = prrompt; - register int c; - char *nline; - char got_eof = 0; - - if (annotation_level > 1 && instream == stdin) - { - local_prompt = alloca ((prrompt == NULL ? 0 : strlen (prrompt)) - + strlen (annotation_suffix) + 40); - if (prrompt == NULL) - local_prompt[0] = '\0'; - else - strcpy (local_prompt, prrompt); - strcat (local_prompt, "\n\032\032"); - strcat (local_prompt, annotation_suffix); - strcat (local_prompt, "\n"); - } - - if (linebuffer == 0) - { - linelength = 80; - linebuffer = (char *) xmalloc (linelength); - } - - p = linebuffer; - - /* 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 - - 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 (source_file_name != NULL) - { - ++source_line_number; - sprintf (source_error, - "%s%s:%d: Error in sourced command file:\n", - source_pre_error, - source_file_name, - source_line_number); - error_pre_print = source_error; - } - - if (annotation_level > 1 && instream == stdin) - { - printf_unfiltered ("\n\032\032pre-"); - printf_unfiltered (annotation_suffix); - printf_unfiltered ("\n"); - } - - /* Don't use fancy stuff if not talking to stdin. */ - if (command_editing_p && instream == stdin - && ISATTY (instream)) - rl = readline (local_prompt); - else - rl = gdb_readline (local_prompt); - - if (annotation_level > 1 && instream == stdin) - { - printf_unfiltered ("\n\032\032post-"); - printf_unfiltered (annotation_suffix); - printf_unfiltered ("\n"); - } - - if (!rl || rl == (char *) EOF) - { - got_eof = 1; - break; - } - if (strlen(rl) + 1 + (p - linebuffer) > linelength) - { - linelength = strlen(rl) + 1 + (p - linebuffer); - nline = (char *) xrealloc (linebuffer, linelength); - p += nline - linebuffer; - linebuffer = nline; - } - p1 = rl; - /* Copy line. Don't copy null at end. (Leaves line alone - if this was just a newline) */ - while (*p1) - *p++ = *p1++; - - free (rl); /* Allocated in readline. */ - - if (p == linebuffer || *(p - 1) != '\\') - break; - - p--; /* Put on top of '\'. */ - local_prompt = (char *) 0; - } - -#ifdef STOP_SIGNAL - if (job_control) - signal (STOP_SIGNAL, SIG_DFL); -#endif - immediate_quit--; - - if (got_eof) - return NULL; - -#define SERVER_COMMAND_LENGTH 7 - server_command = - (p - linebuffer > SERVER_COMMAND_LENGTH) - && STREQN (linebuffer, "server ", SERVER_COMMAND_LENGTH); - if (server_command) - { - /* Note that we don't set `line'. Between this and the check in - dont_repeat, this insures that repeating will still do the - right thing. */ - *p = '\0'; - return linebuffer + SERVER_COMMAND_LENGTH; - } - - /* Do history expansion if that is wished. */ - if (history_expansion_p && instream == stdin - && ISATTY (instream)) - { - char *history_value; - int expanded; - - *p = '\0'; /* Insert null now. */ - expanded = history_expand (linebuffer, &history_value); - if (expanded) - { - /* Print the changes. */ - printf_unfiltered ("%s\n", history_value); - - /* If there was an error, call this function again. */ - if (expanded < 0) - { - free (history_value); - return command_line_input (prrompt, repeat, annotation_suffix); - } - if (strlen (history_value) > linelength) - { - linelength = strlen (history_value) + 1; - linebuffer = (char *) xrealloc (linebuffer, linelength); - } - strcpy (linebuffer, history_value); - p = linebuffer + strlen(linebuffer); - free (history_value); - } - } - - /* If we just got an empty line, and that is supposed - to repeat the previous command, return the value in the - global buffer. */ - if (repeat) - { - if (p == linebuffer) - return line; - p1 = linebuffer; - while (*p1 == ' ' || *p1 == '\t') - p1++; - if (!*p1) - return line; - } - - *p = 0; - - /* Add line to history if appropriate. */ - if (instream == stdin - && ISATTY (stdin) && *linebuffer) - add_history (linebuffer); - - /* Note: lines consisting solely of comments are added to the command - history. This is useful when you type a command, and then - realize you don't want to execute it quite yet. You can comment - out the command and then later fetch it from the value history - and remove the '#'. The kill ring is probably better, but some - people are in the habit of commenting things out. */ - p1 = linebuffer; - while ((c = *p1++) != '\0') - { - if (c == '"') - while ((c = *p1++) != '"') - { - /* Make sure an escaped '"' doesn't make us think the string - is ended. */ - if (c == '\\') - parse_escape (&p1); - if (c == '\0') - break; - } - else if (c == '\'') - while ((c = *p1++) != '\'') - { - /* Make sure an escaped '\'' doesn't make us think the string - is ended. */ - if (c == '\\') - parse_escape (&p1); - if (c == '\0') - break; - } - else if (c == '#') - { - /* Found a comment. */ - p1[-1] = '\0'; - break; - } - } - - /* Save into global buffer if appropriate. */ - if (repeat) - { - if (linelength > linesize) - { - line = xrealloc (line, linelength); - linesize = linelength; - } - strcpy (line, linebuffer); - return line; - } - - return linebuffer; -} - -/* Read lines from the input stream - and accumulate them in a chain of struct command_line's - which is then returned. */ - -struct command_line * -read_command_lines () -{ - struct command_line *first = 0; - register struct command_line *next, *tail = 0; - register char *p, *p1; - struct cleanup *old_chain = 0; - - while (1) - { - dont_repeat (); - p = command_line_input ((char *) NULL, instream == stdin, "commands"); - if (p == NULL) - /* Treat end of file like "end". */ - break; - - /* Remove leading and trailing blanks. */ - while (*p == ' ' || *p == '\t') p++; - p1 = p + strlen (p); - while (p1 != p && (p1[-1] == ' ' || p1[-1] == '\t')) p1--; - - /* Is this "end"? */ - if (p1 - p == 3 && !strncmp (p, "end", 3)) - break; - - /* No => add this line to the chain of command lines. */ - next = (struct command_line *) xmalloc (sizeof (struct command_line)); - next->line = savestring (p, p1 - p); - next->next = 0; - if (tail) - { - tail->next = next; - } - else - { - /* We just read the first line. - From now on, arrange to throw away the lines we have - if we quit or get an error while inside this function. */ - first = next; - old_chain = make_cleanup (free_command_lines, &first); - } - tail = next; - } - - dont_repeat (); - - /* Now we are about to return the chain to our caller, - so freeing it becomes his responsibility. */ - if (first) - discard_cleanups (old_chain); - return first; -} - -/* Free a chain of struct command_line's. */ - -void -free_command_lines (lptr) - struct command_line **lptr; -{ - register struct command_line *l = *lptr; - register struct command_line *next; - - while (l) - { - next = l->next; - free (l->line); - free ((PTR)l); - l = next; - } -} - -/* Add an element to the list of info subcommands. */ - -void -add_info (name, fun, doc) - char *name; - void (*fun) PARAMS ((char *, int)); - char *doc; -{ - add_cmd (name, no_class, fun, doc, &infolist); -} - -/* Add an alias to the list of info subcommands. */ - -void -add_info_alias (name, oldname, abbrev_flag) - char *name; - char *oldname; - int abbrev_flag; -{ - add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist); -} - -/* The "info" command is defined as a prefix, with allow_unknown = 0. - Therefore, its own definition is called only for "info" with no args. */ - -/* ARGSUSED */ -static void -info_command (arg, from_tty) - char *arg; - int from_tty; -{ - printf_unfiltered ("\"info\" must be followed by the name of an info command.\n"); - help_list (infolist, "info ", -1, gdb_stdout); -} - -/* The "complete" command is used by Emacs to implement completion. */ - -/* ARGSUSED */ -static void -complete_command (arg, from_tty) - char *arg; - int from_tty; -{ - int i; - char *completion; - - dont_repeat (); - - if (arg == NULL) - { - rl_line_buffer[0] = '\0'; - rl_point = 0; - } - else - { - strcpy (rl_line_buffer, arg); - rl_point = strlen (arg); - } - - for (completion = symbol_completion_function (rl_line_buffer, i = 0); - completion; - completion = symbol_completion_function (rl_line_buffer, ++i)) - printf_unfiltered ("%s\n", completion); -} - -/* The "show" command with no arguments shows all the settings. */ - -/* ARGSUSED */ -static void -show_command (arg, from_tty) - char *arg; - int from_tty; -{ - cmd_show_list (showlist, from_tty, ""); -} - -/* Add an element to the list of commands. */ - -void -add_com (name, class, fun, doc) - char *name; - enum command_class class; - void (*fun) PARAMS ((char *, int)); - char *doc; -{ - add_cmd (name, class, fun, doc, &cmdlist); -} - -/* Add an alias or abbreviation command to the list of commands. */ - -void -add_com_alias (name, oldname, class, abbrev_flag) - char *name; - char *oldname; - enum command_class class; - int abbrev_flag; -{ - add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist); -} - -void -error_no_arg (why) - char *why; -{ - error ("Argument required (%s).", why); -} - -/* ARGSUSED */ -static void -help_command (command, from_tty) - char *command; - int from_tty; /* Ignored */ -{ - help_cmd (command, gdb_stdout); -} - -static void -validate_comname (comname) - char *comname; -{ - register char *p; - - if (comname == 0) - error_no_arg ("name of command to define"); - - p = comname; - while (*p) - { - if (!isalnum(*p) && *p != '-') - error ("Junk in argument list: \"%s\"", p); - p++; - } -} - -/* This is just a placeholder in the command data structures. */ -static void -user_defined_command (ignore, from_tty) - char *ignore; - int from_tty; -{ -} - -static void -define_command (comname, from_tty) - char *comname; - int from_tty; -{ - register struct command_line *cmds; - register struct cmd_list_element *c, *newc, *hookc = 0; - char *tem = comname; -#define HOOK_STRING "hook-" -#define HOOK_LEN 5 - - validate_comname (comname); - - /* Look it up, and verify that we got an exact match. */ - c = lookup_cmd (&tem, cmdlist, "", -1, 1); - if (c && !STREQ (comname, c->name)) - c = 0; - - if (c) - { - if (c->class == class_user || c->class == class_alias) - tem = "Redefine command \"%s\"? "; - else - tem = "Really redefine built-in command \"%s\"? "; - if (!query (tem, c->name)) - error ("Command \"%s\" not redefined.", c->name); - } - - /* If this new command is a hook, then mark the command which it - is hooking. Note that we allow hooking `help' commands, so that - we can hook the `stop' pseudo-command. */ - - if (!strncmp (comname, HOOK_STRING, HOOK_LEN)) - { - /* Look up cmd it hooks, and verify that we got an exact match. */ - tem = comname+HOOK_LEN; - hookc = lookup_cmd (&tem, cmdlist, "", -1, 0); - if (hookc && !STREQ (comname+HOOK_LEN, hookc->name)) - hookc = 0; - if (!hookc) - { - warning ("Your new `%s' command does not hook any existing command.", - comname); - if (!query ("Proceed? ", (char *)0)) - error ("Not confirmed."); - } - } - - comname = savestring (comname, strlen (comname)); - - /* If the rest of the commands will be case insensitive, this one - should behave in the same manner. */ - 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); - } - - cmds = read_command_lines (); - - if (c && c->class == class_user) - free_command_lines (&c->user_commands); - - newc = add_cmd (comname, class_user, user_defined_command, - (c && c->class == class_user) - ? c->doc : savestring ("User-defined.", 13), &cmdlist); - newc->user_commands = cmds; - - /* If this new command is a hook, then mark both commands as being - tied. */ - if (hookc) - { - hookc->hook = newc; /* Target gets hooked. */ - newc->hookee = hookc; /* We are marked as hooking target cmd. */ - } -} - -static void -document_command (comname, from_tty) - char *comname; - int from_tty; -{ - struct command_line *doclines; - register struct cmd_list_element *c; - char *tem = comname; - - validate_comname (comname); - - c = lookup_cmd (&tem, cmdlist, "", 0, 1); - - 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 (); - - if (c->doc) free (c->doc); - - { - register struct command_line *cl1; - register int len = 0; - - for (cl1 = doclines; cl1; cl1 = cl1->next) - len += strlen (cl1->line) + 1; - - c->doc = (char *) xmalloc (len + 1); - *c->doc = 0; - - for (cl1 = doclines; cl1; cl1 = cl1->next) - { - strcat (c->doc, cl1->line); - if (cl1->next) - strcat (c->doc, "\n"); - } - } - - 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\ -"); -} - -void -print_gdb_version (stream) - GDB_FILE *stream; -{ - fprintf_filtered (stream, "\ -GDB %s (%s", version, host_name); - - if (!STREQ (host_name, target_name)) - fprintf_filtered (stream, " --target %s", target_name); - - fprintf_filtered (stream, "), "); - wrap_here(""); - fprintf_filtered (stream, "Copyright 1994 Free Software Foundation, Inc."); -} - -/* ARGSUSED */ -static void -show_version (args, from_tty) - char *args; - int from_tty; -{ - immediate_quit++; - print_gnu_advertisement (); - print_gdb_version (gdb_stdout); - printf_filtered ("\n"); - immediate_quit--; -} - -/* xgdb calls this to reprint the usual GDB prompt. Obsolete now that xgdb - is obsolete. */ - -void -print_prompt () -{ - printf_unfiltered ("%s", prompt); - gdb_flush (gdb_stdout); -} - -void -quit_command (args, from_tty) - char *args; - int 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."); - } - else - { - if (query ("The program is running. Quit anyway (and kill it)? ")) - target_kill (); - else - error ("Not confirmed."); - } - } - /* UDI wants this, to kill the TIP. */ - target_close (1); - - /* Save the history information if it is appropriate to do so. */ - if (write_history_p && history_filename) - write_history (history_filename); - - exit (0); -} - -/* Returns whether GDB is running on a terminal and whether the user - desires that questions be asked of them on that terminal. */ - -int -input_from_terminal_p () -{ - return gdb_has_a_terminal () && (instream == stdin) & caution; -} - -/* ARGSUSED */ -static void -pwd_command (args, from_tty) - char *args; - int from_tty; -{ - if (args) error ("The \"pwd\" command does not take an argument: %s", args); - getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); - - if (!STREQ (gdb_dirbuf, current_directory)) - printf_unfiltered ("Working directory %s\n (canonically %s).\n", - current_directory, gdb_dirbuf); - else - printf_unfiltered ("Working directory %s.\n", current_directory); -} - -void -cd_command (dir, from_tty) - char *dir; - int from_tty; -{ - int len; - /* Found something other than leading repetitions of "/..". */ - int found_real_path; - char *p; - - /* If the new directory is absolute, repeat is a no-op; if relative, - repeat might be useful but is more likely to be a mistake. */ - dont_repeat (); - - if (dir == 0) - error_no_arg ("new working directory"); - - dir = tilde_expand (dir); - make_cleanup (free, dir); - - if (chdir (dir) < 0) - perror_with_name (dir); - - len = strlen (dir); - dir = savestring (dir, len - (len > 1 && dir[len-1] == '/')); - if (dir[0] == '/') - current_directory = dir; - else - { - if (current_directory[0] == '/' && current_directory[1] == '\0') - current_directory = concat (current_directory, dir, NULL); - else - current_directory = concat (current_directory, "/", dir, NULL); - free (dir); - } - - /* Now simplify any occurrences of `.' and `..' in the pathname. */ - - found_real_path = 0; - for (p = current_directory; *p;) - { - if (p[0] == '/' && p[1] == '.' && (p[2] == 0 || p[2] == '/')) - strcpy (p, p + 2); - else if (p[0] == '/' && p[1] == '.' && p[2] == '.' - && (p[3] == 0 || p[3] == '/')) - { - if (found_real_path) - { - /* Search backwards for the directory just before the "/.." - and obliterate it and the "/..". */ - char *q = p; - while (q != current_directory && q[-1] != '/') - --q; - - if (q == current_directory) - /* current_directory is - a relative pathname ("can't happen"--leave it alone). */ - ++p; - else - { - strcpy (q - 1, p + 3); - p = q - 1; - } - } - else - /* We are dealing with leading repetitions of "/..", for example - "/../..", which is the Mach super-root. */ - p += 3; - } - else - { - found_real_path = 1; - ++p; - } - } - - forget_cached_source_info (); - - if (from_tty) - pwd_command ((char *) 0, 1); -} - -struct source_cleanup_lines_args { - int old_line; - char *old_file; - char *old_pre_error; - char *old_error_pre_print; -}; - -static void -source_cleanup_lines (args) - PTR args; -{ - struct source_cleanup_lines_args *p = - (struct source_cleanup_lines_args *)args; - source_line_number = p->old_line; - source_file_name = p->old_file; - source_pre_error = p->old_pre_error; - error_pre_print = p->old_error_pre_print; -} - -/* ARGSUSED */ -void -source_command (args, from_tty) - char *args; - int from_tty; -{ - FILE *stream; - struct cleanup *old_cleanups; - char *file = args; - struct source_cleanup_lines_args old_lines; - int needed_length; - - if (file == NULL) - { - error ("source command requires pathname of file to source."); - } - - file = tilde_expand (file); - old_cleanups = make_cleanup (free, file); - - stream = fopen (file, FOPEN_RT); - if (stream == 0) - perror_with_name (file); - - make_cleanup (fclose, stream); - - old_lines.old_line = source_line_number; - old_lines.old_file = source_file_name; - old_lines.old_pre_error = source_pre_error; - old_lines.old_error_pre_print = error_pre_print; - make_cleanup (source_cleanup_lines, &old_lines); - source_line_number = 0; - source_file_name = file; - source_pre_error = error_pre_print == NULL ? "" : error_pre_print; - source_pre_error = savestring (source_pre_error, strlen (source_pre_error)); - make_cleanup (free, source_pre_error); - /* This will get set every time we read a line. So it won't stay "" for - long. */ - error_pre_print = ""; - - needed_length = strlen (source_file_name) + strlen (source_pre_error) + 80; - if (source_error_allocated < needed_length) - { - source_error_allocated *= 2; - if (source_error_allocated < needed_length) - source_error_allocated = needed_length; - if (source_error == NULL) - source_error = xmalloc (source_error_allocated); - else - source_error = xrealloc (source_error, source_error_allocated); - } - - read_command_file (stream); - - do_cleanups (old_cleanups); -} - -/* ARGSUSED */ -static void -echo_command (text, from_tty) - char *text; - int from_tty; -{ - char *p = text; - register int c; - - if (text) - while ((c = *p++) != '\0') - { - if (c == '\\') - { - /* \ at end of argument is used after spaces - so they won't be lost. */ - if (*p == 0) - return; - - c = parse_escape (&p); - if (c >= 0) - printf_filtered ("%c", c); - } - else - printf_filtered ("%c", c); - } - - /* Force this output to appear now. */ - wrap_here (""); - gdb_flush (gdb_stdout); -} - - -/* Functions to manipulate command line editing control variables. */ - -/* Number of commands to print in each call to show_commands. */ -#define Hist_print 10 -static void -show_commands (args, from_tty) - char *args; - int from_tty; -{ - /* Index for history commands. Relative to history_base. */ - int offset; - - /* Number of the history entry which we are planning to display next. - Relative to history_base. */ - static int num = 0; - - /* The first command in the history which doesn't exist (i.e. one more - than the number of the last command). Relative to history_base. */ - int hist_len; - - extern HIST_ENTRY *history_get PARAMS ((int)); - - /* Print out some of the commands from the command history. */ - /* First determine the length of the history list. */ - hist_len = history_size; - for (offset = 0; offset < history_size; offset++) - { - if (!history_get (history_base + offset)) - { - hist_len = offset; - break; - } - } - - if (args) - { - if (args[0] == '+' && args[1] == '\0') - /* "info editing +" should print from the stored position. */ - ; - else - /* "info editing " should print around command number . */ - num = (parse_and_eval_address (args) - history_base) - Hist_print / 2; - } - /* "show commands" means print the last Hist_print commands. */ - else - { - num = hist_len - Hist_print; - } - - if (num < 0) - num = 0; - - /* If there are at least Hist_print commands, we want to display the last - Hist_print rather than, say, the last 6. */ - if (hist_len - num < Hist_print) - { - num = hist_len - Hist_print; - if (num < 0) - num = 0; - } - - for (offset = num; offset < num + Hist_print && offset < hist_len; offset++) - { - printf_filtered ("%5d %s\n", history_base + offset, - (history_get (history_base + offset))->line); - } - - /* The next command we want to display is the next one that we haven't - displayed yet. */ - num += Hist_print; - - /* If the user repeats this command with return, it should do what - "show commands +" does. This is unnecessary if arg is null, - because "show commands +" is not useful after "show commands". */ - if (from_tty && args) - { - args[0] = '+'; - args[1] = '\0'; - } -} - -/* Called by do_setshow_command. */ -/* ARGSUSED */ -static void -set_history_size_command (args, from_tty, c) - char *args; - int from_tty; - struct cmd_list_element *c; -{ - if (history_size == INT_MAX) - unstifle_history (); - else if (history_size >= 0) - stifle_history (history_size); - else - { - history_size = INT_MAX; - error ("History size must be non-negative"); - } -} - -/* ARGSUSED */ -static void -set_history (args, from_tty) - char *args; - int from_tty; -{ - printf_unfiltered ("\"set history\" must be followed by the name of a history subcommand.\n"); - help_list (sethistlist, "set history ", -1, gdb_stdout); -} - -/* ARGSUSED */ -static void -show_history (args, from_tty) - char *args; - int from_tty; -{ - cmd_show_list (showhistlist, from_tty, ""); -} - -int info_verbose = 0; /* Default verbose msgs off */ - -/* Called by do_setshow_command. An elaborate joke. */ -/* ARGSUSED */ -static void -set_verbose (args, from_tty, c) - char *args; - int from_tty; - struct cmd_list_element *c; -{ - char *cmdname = "verbose"; - struct cmd_list_element *showcmd; - - showcmd = lookup_cmd_1 (&cmdname, showlist, NULL, 1); - - if (info_verbose) - { - c->doc = "Set verbose printing of informational messages."; - showcmd->doc = "Show verbose printing of informational messages."; - } - else - { - c->doc = "Set verbosity."; - showcmd->doc = "Show verbosity."; - } -} - -static void -float_handler (signo) -int signo; -{ - /* This message is based on ANSI C, section 4.7. Note that integer - divide by zero causes this, so "float" is a misnomer. */ - signal (SIGFPE, float_handler); - error ("Erroneous arithmetic operation."); -} - - -static void -init_cmd_lists () -{ - cmdlist = NULL; - infolist = NULL; - enablelist = NULL; - disablelist = NULL; - deletelist = NULL; - enablebreaklist = NULL; - setlist = NULL; - unsetlist = NULL; - showlist = NULL; - sethistlist = NULL; - showhistlist = NULL; - unsethistlist = NULL; -#if MAINTENANCE_CMDS - maintenancelist = NULL; - maintenanceinfolist = NULL; - maintenanceprintlist = NULL; -#endif - setprintlist = NULL; - showprintlist = NULL; - setchecklist = NULL; - showchecklist = NULL; -} - -/* Init the history buffer. Note that we are called after the init file(s) - * have been read so that the user can change the history file via his - * .gdbinit file (for instance). The GDBHISTFILE environment variable - * overrides all of this. - */ - -void -init_history() -{ - char *tmpenv; - - tmpenv = getenv ("HISTSIZE"); - if (tmpenv) - history_size = atoi (tmpenv); - else if (!history_size) - history_size = 256; - - stifle_history (history_size); - - tmpenv = getenv ("GDBHISTFILE"); - if (tmpenv) - history_filename = savestring (tmpenv, strlen(tmpenv)); - else if (!history_filename) { - /* We include the current directory so that if the user changes - directories the file written will be the same as the one - that was read. */ - history_filename = concat (current_directory, "/.gdb_history", NULL); - } - read_history (history_filename); -} - -static void -init_main () -{ - struct cmd_list_element *c; - -#ifdef DEFAULT_PROMPT - prompt = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT)); -#else - prompt = savestring ("(gdb) ", 6); -#endif -#ifdef KERNEL_DEBUG - if (kernel_debugging) - prompt = savestring ("(kgdb) ", 7); -#endif - - /* Set the important stuff up for command editing. */ - command_editing_p = 1; - history_expansion_p = 0; - write_history_p = 0; - - /* Setup important stuff for command line editing. */ - rl_completion_entry_function = (int (*)()) symbol_completion_function; - rl_completer_word_break_characters = gdb_completer_word_break_characters; - rl_completer_quote_characters = gdb_completer_quote_characters; - rl_readline_name = "gdb"; - - /* Define the classes of commands. - They will appear in the help list in the reverse of this order. */ - - add_cmd ("internals", class_maintenance, NO_FUNCTION, - "Maintenance commands.\n\ -Some gdb commands are provided just for use by gdb maintainers.\n\ -These commands are subject to frequent change, and may not be as\n\ -well documented as user commands.", - &cmdlist); - add_cmd ("obscure", class_obscure, NO_FUNCTION, "Obscure features.", &cmdlist); - add_cmd ("aliases", class_alias, NO_FUNCTION, "Aliases of other commands.", &cmdlist); - add_cmd ("user-defined", class_user, NO_FUNCTION, "User-defined commands.\n\ -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); - 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); - add_cmd ("stack", class_stack, NO_FUNCTION, "Examining the stack.\n\ -The stack is made up of stack frames. Gdb assigns numbers to stack frames\n\ -counting from zero for the innermost (currently executing) frame.\n\n\ -At any time gdb identifies one frame as the \"selected\" frame.\n\ -Variable lookups are done with respect to the selected frame.\n\ -When the program being debugged stops, gdb selects the innermost frame.\n\ -The commands below can be used to select other frames by number or address.", - &cmdlist); - add_cmd ("running", class_run, NO_FUNCTION, "Running the program.", &cmdlist); - - add_com ("pwd", class_files, pwd_command, - "Print working directory. This is used for your program as well."); - c = add_cmd ("cd", class_files, cd_command, - "Set working directory to DIR for debugger and program being debugged.\n\ -The change does not take effect for the program being debugged\n\ -until the next time it is started.", &cmdlist); - c->completer = filename_completer; - - add_show_from_set - (add_set_cmd ("prompt", class_support, var_string, (char *)&prompt, - "Set gdb's prompt", - &setlist), - &showlist); - - add_com ("echo", class_support, echo_command, - "Print a constant string. Give string as argument.\n\ -C escape sequences may be used in the argument.\n\ -No newline is added at the end of the argument;\n\ -use \"\\n\" if you want a newline to be printed.\n\ -Since leading and trailing whitespace are ignored in command arguments,\n\ -if you want to print some you must use \"\\\" before leading whitespace\n\ -to be printed or after trailing whitespace."); - add_com ("document", class_support, document_command, - "Document a user-defined command.\n\ -Give command name as argument. Give documentation on following lines.\n\ -End with a line of just \"end\"."); - add_com ("define", class_support, define_command, - "Define a new command name. Command name is argument.\n\ -Definition appears on following lines, one command per line.\n\ -End with a line of just \"end\".\n\ -Use the \"document\" command to give documentation for the new command.\n\ -Commands defined in this way do not take arguments."); - -#ifdef __STDC__ - c = add_cmd ("source", class_support, source_command, - "Read commands from a file named FILE.\n\ -Note that the file \"" GDBINIT_FILENAME "\" is read automatically in this way\n\ -when gdb is started.", &cmdlist); -#else - /* Punt file name, we can't help it easily. */ - c = add_cmd ("source", class_support, source_command, - "Read commands from a file named FILE.\n\ -Note that the file \".gdbinit\" is read automatically in this way\n\ -when gdb is started.", &cmdlist); -#endif - c->completer = filename_completer; - - add_com ("quit", class_support, quit_command, "Exit gdb."); - add_com ("help", class_support, help_command, "Print list of commands."); - add_com_alias ("q", "quit", class_support, 1); - add_com_alias ("h", "help", class_support, 1); - - - c = add_set_cmd ("verbose", class_support, var_boolean, (char *)&info_verbose, - "Set ", - &setlist), - add_show_from_set (c, &showlist); - c->function.sfunc = set_verbose; - set_verbose (NULL, 0, c); - - 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\ -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); - - add_prefix_cmd ("history", class_support, set_history, - "Generic command for setting command history parameters.", - &sethistlist, "set history ", 0, &setlist); - add_prefix_cmd ("history", class_support, show_history, - "Generic command for showing command history parameters.", - &showhistlist, "show history ", 0, &showlist); - - add_show_from_set - (add_set_cmd ("expansion", no_class, var_boolean, (char *)&history_expansion_p, - "Set history expansion on command input.\n\ -Without an argument, history expansion is enabled.", &sethistlist), - &showhistlist); - - 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\ -Without an argument, saving is enabled.", &sethistlist), - &showhistlist); - - c = add_set_cmd ("size", no_class, var_integer, (char *)&history_size, - "Set the size of the command history, \n\ -ie. the number of previous commands to keep a record of.", &sethistlist); - add_show_from_set (c, &showhistlist); - c->function.sfunc = set_history_size_command; - - add_show_from_set - (add_set_cmd ("filename", no_class, var_filename, (char *)&history_filename, - "Set the filename in which to record the command history\n\ - (the list of previous commands of which a record is kept).", &sethistlist), - &showhistlist); - - add_show_from_set - (add_set_cmd ("confirm", class_support, var_boolean, - (char *)&caution, - "Set whether to confirm potentially dangerous operations.", - &setlist), - &showlist); - - add_prefix_cmd ("info", class_info, info_command, - "Generic command for showing things about the program being debugged.", - &infolist, "info ", 0, &cmdlist); - add_com_alias ("i", "info", class_info, 1); - - add_com ("complete", class_obscure, complete_command, - "List the completions for the rest of the line as a command."); - - add_prefix_cmd ("show", class_info, show_command, - "Generic command for showing things about the debugger.", - &showlist, "show ", 0, &cmdlist); - /* Another way to get at the same thing. */ - add_info ("set", show_command, "Show all GDB settings."); - - add_cmd ("commands", no_class, show_commands, - "Show the the history of commands you typed.\n\ -You can supply a command number to start with, or a `+' to start after\n\ -the previous command number shown.", - &showlist); - - add_cmd ("version", no_class, show_version, - "Show what version of GDB this is.", &showlist); - - /* If target is open when baud changes, it doesn't take effect until the - next open (I think, not sure). */ - add_show_from_set (add_set_cmd ("remotebaud", no_class, - var_zinteger, (char *)&baud_rate, - "Set baud rate for remote serial I/O.\n\ -This value is used to set the speed of the serial port when debugging\n\ -using remote targets.", &setlist), - &showlist); - - add_show_from_set ( - add_set_cmd ("remotedebug", no_class, var_zinteger, (char *)&remote_debug, - "Set debugging of remote protocol.\n\ -When enabled, each packet sent or received with the remote target\n\ -is displayed.", &setlist), - &showlist); -} diff --git a/gnu/usr.bin/gdb/gdb/top.h b/gnu/usr.bin/gdb/gdb/top.h deleted file mode 100644 index 6ae28a2..0000000 --- a/gnu/usr.bin/gdb/gdb/top.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Top level stuff for GDB, the GNU debugger. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 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. */ - -/* From top.c. */ -extern char *line; -extern int linesize; -extern FILE *instream; -extern char gdb_dirbuf[1024]; -extern int inhibit_gdbinit; -extern int epoch_interface; -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; - -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 void quit_command PARAMS ((char *, int)); - -/* From random places. */ -extern int mapped_symbol_files; -extern int readnow_symbol_files; -#define ALL_CLEANUPS ((struct cleanup *)0) diff --git a/gnu/usr.bin/gdb/gdb/typeprint.c b/gnu/usr.bin/gdb/gdb/typeprint.c deleted file mode 100644 index 785ec61..0000000 --- a/gnu/usr.bin/gdb/gdb/typeprint.c +++ /dev/null @@ -1,297 +0,0 @@ -/* Language independent support for printing types for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 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. */ - -#include "defs.h" -#include "obstack.h" -#include "bfd.h" /* Binary File Description */ -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "value.h" -#include "gdbcore.h" -#include "command.h" -#include "gdbcmd.h" -#include "target.h" -#include "language.h" -#include "demangle.h" - -#include -#include - -static void -ptype_command PARAMS ((char *, int)); - -static struct type * -ptype_eval PARAMS ((struct expression *)); - -static void -whatis_command PARAMS ((char *, int)); - -static void -whatis_exp PARAMS ((char *, int)); - -/* Print a description of a type TYPE in the form of a declaration of a - variable named VARSTRING. (VARSTRING is demangled if necessary.) - Output goes to STREAM (via stdio). - If SHOW is positive, we show the contents of the outermost level - of structure even if there is a type name that could be used instead. - If SHOW is negative, we never show the details of elements' types. */ - -void -type_print (type, varstring, stream, show) - struct type *type; - char *varstring; - GDB_FILE *stream; - int show; -{ - LA_PRINT_TYPE (type, varstring, stream, show, 0); -} - -/* Print type of EXP, or last thing in value history if EXP == NULL. - show is passed to type_print. */ - -static void -whatis_exp (exp, show) - char *exp; - int show; -{ - struct expression *expr; - register value_ptr val; - register struct cleanup *old_chain = NULL; - - if (exp) - { - expr = parse_expression (exp); - old_chain = make_cleanup (free_current_contents, &expr); - val = evaluate_type (expr); - } - else - val = access_value_history (0); - - printf_filtered ("type = "); - type_print (VALUE_TYPE (val), "", gdb_stdout, show); - printf_filtered ("\n"); - - if (exp) - do_cleanups (old_chain); -} - -/* ARGSUSED */ -static void -whatis_command (exp, from_tty) - char *exp; - int from_tty; -{ - /* Most of the time users do not want to see all the fields - in a structure. If they do they can use the "ptype" command. - Hence the "-1" below. */ - whatis_exp (exp, -1); -} - -/* Simple subroutine for ptype_command. */ - -static struct type * -ptype_eval (exp) - struct expression *exp; -{ - if (exp->elts[0].opcode == OP_TYPE) - { - return (exp->elts[1].type); - } - else - { - return (NULL); - } -} - -/* TYPENAME is either the name of a type, or an expression. */ - -/* ARGSUSED */ -static void -ptype_command (typename, from_tty) - char *typename; - int from_tty; -{ - register struct type *type; - struct expression *expr; - register struct cleanup *old_chain; - - if (typename == NULL) - { - /* Print type of last thing in value history. */ - whatis_exp (typename, 1); - } - else - { - expr = parse_expression (typename); - old_chain = make_cleanup (free_current_contents, &expr); - type = ptype_eval (expr); - if (type != NULL) - { - /* User did "ptype " */ - printf_filtered ("type = "); - type_print (type, "", gdb_stdout, 1); - printf_filtered ("\n"); - do_cleanups (old_chain); - } - else - { - /* User did "ptype " */ - do_cleanups (old_chain); - whatis_exp (typename, 1); - } - } -} - -/* 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, - array bounds may be characters or booleans in some languages, and this - allows the ranges to be printed in their "natural" form rather than as - decimal integer values. - - FIXME: This is here simply because only the type printing routines - currently use it, and it wasn't clear if it really belonged somewhere - else (like printcmd.c). There are a lot of other gdb routines that do - something similar, but they are generally concerned with printing values - that come from the inferior in target byte order and target size. */ - -void -print_type_scalar (type, val, stream) - struct type *type; - LONGEST val; - GDB_FILE *stream; -{ - unsigned int i; - unsigned len; - - switch (TYPE_CODE (type)) - { - - case TYPE_CODE_ENUM: - len = TYPE_NFIELDS (type); - for (i = 0; i < len; i++) - { - if (TYPE_FIELD_BITPOS (type, i) == val) - { - break; - } - } - if (i < len) - { - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } - else - { - print_longest (stream, 'd', 0, val); - } - break; - - case TYPE_CODE_INT: - print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, val); - break; - - case TYPE_CODE_CHAR: - LA_PRINT_CHAR ((unsigned char) val, stream); - break; - - case TYPE_CODE_BOOL: - fprintf_filtered (stream, val ? "TRUE" : "FALSE"); - break; - - case TYPE_CODE_UNDEF: - case TYPE_CODE_PTR: - case TYPE_CODE_ARRAY: - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - case TYPE_CODE_FUNC: - case TYPE_CODE_FLT: - case TYPE_CODE_VOID: - case TYPE_CODE_SET: - case TYPE_CODE_RANGE: - case TYPE_CODE_STRING: - case TYPE_CODE_ERROR: - case TYPE_CODE_MEMBER: - case TYPE_CODE_METHOD: - case TYPE_CODE_REF: - error ("internal error: unhandled type in print_type_scalar"); - break; - - default: - error ("Invalid type code in symbol table."); - } - gdb_flush (stream); -} - -#if MAINTENANCE_CMDS - -/* Dump details of a type specified either directly or indirectly. - Uses the same sort of type lookup mechanism as ptype_command() - and whatis_command(). */ - -void -maintenance_print_type (typename, from_tty) - char *typename; - int from_tty; -{ - register value_ptr val; - register struct type *type; - register struct cleanup *old_chain; - struct expression *expr; - - if (typename != NULL) - { - expr = parse_expression (typename); - old_chain = make_cleanup (free_current_contents, &expr); - if (expr -> elts[0].opcode == OP_TYPE) - { - /* The user expression names a type directly, just use that type. */ - type = expr -> elts[1].type; - } - else - { - /* The user expression may name a type indirectly by naming an - object of that type. Find that indirectly named type. */ - val = evaluate_type (expr); - type = VALUE_TYPE (val); - } - if (type != NULL) - { - recursive_dump_type (type, 0); - } - do_cleanups (old_chain); - } -} - -#endif /* MAINTENANCE_CMDS */ - - -void -_initialize_typeprint () -{ - - add_com ("ptype", class_vars, ptype_command, - "Print definition of type TYPE.\n\ -Argument may be a type name defined by typedef, or \"struct STRUCT-TAG\"\n\ -or \"class CLASS-NAME\" or \"union UNION-TAG\" or \"enum ENUM-TAG\".\n\ -The selected stack frame's lexical context is used to look up the name."); - - add_com ("whatis", class_vars, whatis_command, - "Print data type of expression EXP."); - -} diff --git a/gnu/usr.bin/gdb/gdb/typeprint.h b/gnu/usr.bin/gdb/gdb/typeprint.h deleted file mode 100644 index eead5f6..0000000 --- a/gnu/usr.bin/gdb/gdb/typeprint.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Language independent support for printing types for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 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. */ - -void -print_type_scalar PARAMS ((struct type *type, LONGEST, GDB_FILE *)); diff --git a/gnu/usr.bin/gdb/gdb/utils.c b/gnu/usr.bin/gdb/gdb/utils.c deleted file mode 100644 index 5749013..0000000 --- a/gnu/usr.bin/gdb/gdb/utils.c +++ /dev/null @@ -1,1790 +0,0 @@ -/* General utility routines for GDB, the GNU debugger. - Copyright 1986, 1989, 1990, 1991, 1992 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 "defs.h" -#if !defined(__GO32__) -#include -#include -#include -#endif -#include -#include -#include - -#include "signals.h" -#include "gdbcmd.h" -#include "serial.h" -#include "bfd.h" -#include "target.h" -#include "demangle.h" -#include "expression.h" -#include "language.h" -#include "annotate.h" - -#include "readline.h" - -/* readline defines this. */ -#undef savestring - -/* Prototypes for local functions */ - -#if defined (NO_MMALLOC) || defined (NO_MMALLOC_CHECK) -#else - -static void -malloc_botch PARAMS ((void)); - -#endif /* NO_MMALLOC, etc */ - -static void -fatal_dump_core (); /* Can't prototype with usage... */ - -static void -prompt_for_continue PARAMS ((void)); - -static void -set_width_command PARAMS ((char *, int, struct cmd_list_element *)); - -/* 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 - -/* Chain of cleanup actions established with make_cleanup, - to be executed if an error happens. */ - -static struct cleanup *cleanup_chain; - -/* Nonzero if we have job control. */ - -int job_control; - -/* Nonzero means a quit has been requested. */ - -int quit_flag; - -/* Nonzero means quit immediately if Control-C is typed now, rather - than waiting until QUIT is executed. Be careful in setting this; - code which executes with immediate_quit set has to be very careful - about being able to deal with being interrupted at any time. It is - almost always better to use QUIT; the only exception I can think of - is being able to quit out of a system call (using EINTR loses if - the SIGINT happens between the previous QUIT and the system call). - To immediately quit in the case in which a SIGINT happens between - the previous QUIT and setting immediate_quit (desirable anytime we - expect to block), call QUIT after setting immediate_quit. */ - -int immediate_quit; - -/* Nonzero means that encoded C++ names should be printed out in their - C++ form rather than raw. */ - -int demangle = 1; - -/* Nonzero means that encoded C++ names should be printed out in their - C++ form even in assembler language displays. If this is set, but - DEMANGLE is zero, names are printed raw, i.e. DEMANGLE controls. */ - -int asm_demangle = 0; - -/* Nonzero means that strings with character values >0x7F should be printed - as octal escapes. Zero means just print the value (e.g. it's an - international character, and the terminal or window can cope.) */ - -int sevenbit_strings = 0; - -/* String to be printed before error messages, if any. */ - -char *error_pre_print; -char *warning_pre_print = "\nwarning: "; - -/* Add a new cleanup to the cleanup_chain, - and return the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. - Args are FUNCTION to clean up with, and ARG to pass to it. */ - -struct cleanup * -make_cleanup (function, arg) - void (*function) PARAMS ((PTR)); - PTR arg; -{ - register struct cleanup *new - = (struct cleanup *) xmalloc (sizeof (struct cleanup)); - register struct cleanup *old_chain = cleanup_chain; - - new->next = cleanup_chain; - new->function = function; - new->arg = arg; - cleanup_chain = new; - - return old_chain; -} - -/* Discard cleanups and do the actions they describe - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -do_cleanups (old_chain) - register struct cleanup *old_chain; -{ - register struct cleanup *ptr; - while ((ptr = cleanup_chain) != old_chain) - { - cleanup_chain = ptr->next; /* Do this first incase recursion */ - (*ptr->function) (ptr->arg); - free (ptr); - } -} - -/* Discard cleanups, not doing the actions they describe, - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -discard_cleanups (old_chain) - register struct cleanup *old_chain; -{ - register struct cleanup *ptr; - while ((ptr = cleanup_chain) != old_chain) - { - cleanup_chain = ptr->next; - free ((PTR)ptr); - } -} - -/* Set the cleanup_chain to 0, and return the old cleanup chain. */ -struct cleanup * -save_cleanups () -{ - struct cleanup *old_chain = cleanup_chain; - - cleanup_chain = 0; - return old_chain; -} - -/* Restore the cleanup chain from a previously saved chain. */ -void -restore_cleanups (chain) - struct cleanup *chain; -{ - cleanup_chain = chain; -} - -/* This function is useful for cleanups. - Do - - foo = xmalloc (...); - old_chain = make_cleanup (free_current_contents, &foo); - - to arrange to free the object thus allocated. */ - -void -free_current_contents (location) - char **location; -{ - free (*location); -} - -/* Provide a known function that does nothing, to use as a base for - for a possibly long chain of cleanups. This is useful where we - use the cleanup chain for handling normal cleanups as well as dealing - with cleanups that need to be done as a result of a call to error(). - In such cases, we may not be certain where the first cleanup is, unless - we have a do-nothing one to always use as the base. */ - -/* ARGSUSED */ -void -null_cleanup (arg) - char **arg; -{ -} - - -/* Provide a hook for modules wishing to print their own warning messages - to set up the terminal state in a compatible way, without them having - to import all the target_<...> macros. */ - -void -warning_setup () -{ - target_terminal_ours (); - wrap_here(""); /* Force out any buffered output */ - gdb_flush (gdb_stdout); -} - -/* Print a warning message. - The first argument STRING is the warning message, used as a fprintf string, - and the remaining args are passed as arguments to it. - The primary difference between warnings and errors is that a warning - does not force the return to command level. */ - -/* VARARGS */ -void -warning (va_alist) - va_dcl -{ - va_list args; - char *string; - - va_start (args); - target_terminal_ours (); - wrap_here(""); /* Force out any buffered output */ - gdb_flush (gdb_stdout); - if (warning_pre_print) - fprintf_unfiltered (gdb_stderr, warning_pre_print); - string = va_arg (args, char *); - 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 - this, output the error message (use filtered output), and then call - return_to_top_level (RETURN_ERROR). error() provides a convenient way to - do this for the special case that the error message can be formatted with - a single printf call, but this is more general. */ -void -error_begin () -{ - target_terminal_ours (); - wrap_here (""); /* Force out any buffered output */ - gdb_flush (gdb_stdout); - - annotate_error_begin (); - - if (error_pre_print) - fprintf_filtered (gdb_stderr, error_pre_print); -} - -/* Print an error message and return to command level. - The first argument STRING is the error message, used as a fprintf string, - and the remaining args are passed as arguments to it. */ - -/* VARARGS */ -NORETURN void -error (va_alist) - va_dcl -{ - va_list args; - char *string; - - error_begin (); - va_start (args); - string = va_arg (args, char *); - vfprintf_filtered (gdb_stderr, string, args); - fprintf_filtered (gdb_stderr, "\n"); - va_end (args); - return_to_top_level (RETURN_ERROR); -} - -/* Print an error message and exit reporting failure. - This is for a error that we cannot continue from. - The arguments are printed a la printf. - - This function cannot be declared volatile (NORETURN) in an - ANSI environment because exit() is not declared volatile. */ - -/* VARARGS */ -NORETURN void -fatal (va_alist) - va_dcl -{ - va_list args; - char *string; - - va_start (args); - string = va_arg (args, char *); - fprintf_unfiltered (gdb_stderr, "\ngdb: "); - vfprintf_unfiltered (gdb_stderr, string, args); - fprintf_unfiltered (gdb_stderr, "\n"); - va_end (args); - exit (1); -} - -/* Print an error message and exit, dumping core. - The arguments are printed a la printf (). */ - -/* VARARGS */ -static void -fatal_dump_core (va_alist) - va_dcl -{ - va_list args; - char *string; - - va_start (args); - string = va_arg (args, char *); - /* "internal error" is always correct, since GDB should never dump - core, no matter what the input. */ - fprintf_unfiltered (gdb_stderr, "\ngdb internal error: "); - vfprintf_unfiltered (gdb_stderr, string, args); - fprintf_unfiltered (gdb_stderr, "\n"); - va_end (args); - - signal (SIGQUIT, SIG_DFL); - kill (getpid (), SIGQUIT); - /* We should never get here, but just in case... */ - exit (1); -} - -/* The strerror() function can return NULL for errno values that are - out of range. Provide a "safe" version that always returns a - printable string. */ - -char * -safe_strerror (errnum) - int errnum; -{ - char *msg; - static char buf[32]; - - if ((msg = strerror (errnum)) == NULL) - { - sprintf (buf, "(undocumented errno %d)", errnum); - msg = buf; - } - return (msg); -} - -/* The strsignal() function can return NULL for signal values that are - out of range. Provide a "safe" version that always returns a - printable string. */ - -char * -safe_strsignal (signo) - int signo; -{ - char *msg; - static char buf[32]; - - if ((msg = strsignal (signo)) == NULL) - { - sprintf (buf, "(undocumented signal %d)", signo); - msg = buf; - } - return (msg); -} - - -/* Print the system error message for errno, and also mention STRING - as the file name for which the error was encountered. - Then return to command level. */ - -void -perror_with_name (string) - char *string; -{ - char *err; - char *combined; - - err = safe_strerror (errno); - combined = (char *) alloca (strlen (err) + strlen (string) + 3); - strcpy (combined, string); - strcat (combined, ": "); - strcat (combined, err); - - /* I understand setting these is a matter of taste. Still, some people - may clear errno but not know about bfd_error. Doing this here is not - unreasonable. */ - bfd_set_error (bfd_error_no_error); - errno = 0; - - error ("%s.", combined); -} - -/* Print the system error message for ERRCODE, and also mention STRING - as the file name for which the error was encountered. */ - -void -print_sys_errmsg (string, errcode) - char *string; - int errcode; -{ - char *err; - char *combined; - - err = safe_strerror (errcode); - combined = (char *) alloca (strlen (err) + strlen (string) + 3); - strcpy (combined, string); - strcat (combined, ": "); - strcat (combined, err); - - /* We want anything which was printed on stdout to come out first, before - this message. */ - gdb_flush (gdb_stdout); - fprintf_unfiltered (gdb_stderr, "%s.\n", combined); -} - -/* Control C eventually causes this to be called, at a convenient time. */ - -void -quit () -{ - serial_t gdb_stdout_serial = serial_fdopen (1); - - target_terminal_ours (); - - /* We want all output to appear now, before we print "Quit". We - have 3 levels of buffering we have to flush (it's possible that - some of these should be changed to flush the lower-level ones - too): */ - - /* 1. The _filtered buffer. */ - wrap_here ((char *)0); - - /* 2. The stdio buffer. */ - gdb_flush (gdb_stdout); - gdb_flush (gdb_stderr); - - /* 3. The system-level buffer. */ - SERIAL_FLUSH_OUTPUT (gdb_stdout_serial); - SERIAL_UN_FDOPEN (gdb_stdout_serial); - - annotate_error_begin (); - - /* Don't use *_filtered; we don't want to prompt the user to continue. */ - if (error_pre_print) - fprintf_unfiltered (gdb_stderr, error_pre_print); - - if (job_control - /* If there is no terminal switching for this target, then we can't - possibly get screwed by the lack of job control. */ - || current_target->to_terminal_ours == NULL) - fprintf_unfiltered (gdb_stderr, "Quit\n"); - else - fprintf_unfiltered (gdb_stderr, - "Quit (expect signal SIGINT when the program is resumed)\n"); - return_to_top_level (RETURN_QUIT); -} - - -#ifdef __GO32__ - -/* In the absence of signals, poll keyboard for a quit. - Called from #define QUIT pollquit() in xm-go32.h. */ - -void -pollquit() -{ - if (kbhit ()) - { - int k = getkey (); - if (k == 1) { - quit_flag = 1; - quit(); - } - else if (k == 2) { - immediate_quit = 1; - quit (); - } - else - { - /* We just ignore it */ - fprintf_unfiltered (gdb_stderr, "CTRL-A to quit, CTRL-B to quit harder\n"); - } - } -} - - -#endif -#ifdef __GO32__ -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"); - } - } -} -#else -void notice_quit() -{ - /* Done by signals */ -} -#endif -/* Control C comes here */ - -void -request_quit (signo) - int signo; -{ - quit_flag = 1; - - /* Restore the signal handler. Harmless with BSD-style signals, needed - for System V-style signals. So just always do it, rather than worrying - about USG defines and stuff like that. */ - signal (signo, request_quit); - -#ifdef REQUEST_QUIT - REQUEST_QUIT; -#else - if (immediate_quit) - quit (); -#endif -} - - -/* Memory management stuff (malloc friends). */ - -#if defined (NO_MMALLOC) - -PTR -mmalloc (md, size) - PTR md; - long size; -{ - return (malloc (size)); -} - -PTR -mrealloc (md, ptr, size) - PTR md; - PTR ptr; - long size; -{ - if (ptr == 0) /* Guard against old realloc's */ - return malloc (size); - else - return realloc (ptr, size); -} - -void -mfree (md, ptr) - PTR md; - PTR ptr; -{ - free (ptr); -} - -#endif /* NO_MMALLOC */ - -#if defined (NO_MMALLOC) || defined (NO_MMALLOC_CHECK) - -void -init_malloc (md) - PTR md; -{ -} - -#else /* have mmalloc and want corruption checking */ - -static void -malloc_botch () -{ - fatal_dump_core ("Memory corruption"); -} - -/* Attempt to install hooks in mmalloc/mrealloc/mfree for the heap specified - 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 - 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 - installed before the first mmalloc. However, anytime after we have called - mmcheck the first time to install the checking hooks, we can call it again - to update the function pointer to the memory corruption handler. - - Returns zero on failure, non-zero on success. */ - -void -init_malloc (md) - PTR md; -{ - if (!mmcheck (md, malloc_botch)) - { - warning ("internal error: failed to install memory consistency checks"); - } - - mmtrace (); -} - -#endif /* Have mmalloc and want corruption checking */ - -/* Called when a memory allocation fails, with the number of bytes of - memory requested in SIZE. */ - -NORETURN void -nomem (size) - long size; -{ - if (size > 0) - { - fatal ("virtual memory exhausted: can't allocate %ld bytes.", size); - } - else - { - fatal ("virtual memory exhausted."); - } -} - -/* Like mmalloc but get error if no storage available, and protect against - the caller wanting to allocate zero bytes. Whether to return NULL for - a zero byte request, or translate the request into a request for one - byte of zero'd storage, is a religious issue. */ - -PTR -xmmalloc (md, size) - PTR md; - long size; -{ - register PTR val; - - if (size == 0) - { - val = NULL; - } - else if ((val = mmalloc (md, size)) == NULL) - { - nomem (size); - } - return (val); -} - -/* Like mrealloc but get error if no storage available. */ - -PTR -xmrealloc (md, ptr, size) - PTR md; - PTR ptr; - long size; -{ - register PTR val; - - if (ptr != NULL) - { - val = mrealloc (md, ptr, size); - } - else - { - val = mmalloc (md, size); - } - if (val == NULL) - { - nomem (size); - } - return (val); -} - -/* Like malloc but get error if no storage available, and protect against - the caller wanting to allocate zero bytes. */ - -PTR -xmalloc (size) - long size; -{ - return (xmmalloc ((PTR) NULL, size)); -} - -/* Like mrealloc but get error if no storage available. */ - -PTR -xrealloc (ptr, size) - PTR ptr; - long size; -{ - return (xmrealloc ((PTR) NULL, ptr, size)); -} - - -/* My replacement for the read system call. - Used like `read' but keeps going if `read' returns too soon. */ - -int -myread (desc, addr, len) - int desc; - char *addr; - int len; -{ - register int val; - int orglen = len; - - while (len > 0) - { - val = read (desc, addr, len); - if (val < 0) - return val; - if (val == 0) - return orglen - len; - len -= val; - addr += val; - } - return orglen; -} - -/* Make a copy of the string at PTR with SIZE characters - (and add a null character at the end in the copy). - Uses malloc to get the space. Returns the address of the copy. */ - -char * -savestring (ptr, size) - const char *ptr; - int size; -{ - register char *p = (char *) xmalloc (size + 1); - memcpy (p, ptr, size); - p[size] = 0; - return p; -} - -char * -msavestring (md, ptr, size) - PTR md; - const char *ptr; - int size; -{ - register char *p = (char *) xmmalloc (md, size + 1); - memcpy (p, ptr, size); - p[size] = 0; - return p; -} - -/* The "const" is so it compiles under DGUX (which prototypes strsave - in . FIXME: This should be named "xstrsave", shouldn't it? - Doesn't real strsave return NULL if out of memory? */ -char * -strsave (ptr) - const char *ptr; -{ - return savestring (ptr, strlen (ptr)); -} - -char * -mstrsave (md, ptr) - PTR md; - const char *ptr; -{ - return (msavestring (md, ptr, strlen (ptr))); -} - -void -print_spaces (n, file) - register int n; - register FILE *file; -{ - while (n-- > 0) - fputc (' ', file); -} - -/* Print a host address. */ - -void -gdb_print_address (addr, stream) - PTR addr; - GDB_FILE *stream; -{ - - /* We could use the %p conversion specifier to fprintf if we had any - way of knowing whether this host supports it. But the following - should work on the Alpha and on 32 bit machines. */ - - fprintf_filtered (stream, "0x%lx", (unsigned long)addr); -} - -/* Ask user a y-or-n question and return 1 iff answer is yes. - Takes three args which are given to printf to print the question. - The first, a control string, should end in "? ". - It should not say how to answer, because we do that. */ - -/* VARARGS */ -int -query (va_alist) - va_dcl -{ - va_list args; - char *ctlstr; - register int answer; - register int ans2; - int retval; - - /* Automatically answer "yes" if input is not from a terminal. */ - if (!input_from_terminal_p ()) - return 1; - - while (1) - { - wrap_here (""); /* Flush any buffered output */ - gdb_flush (gdb_stdout); - - if (annotation_level > 1) - printf_filtered ("\n\032\032pre-query\n"); - - va_start (args); - ctlstr = va_arg (args, char *); - vfprintf_filtered (gdb_stdout, ctlstr, args); - va_end (args); - printf_filtered ("(y or n) "); - - if (annotation_level > 1) - printf_filtered ("\n\032\032query\n"); - - gdb_flush (gdb_stdout); - answer = fgetc (stdin); - 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 */ - do - { - ans2 = fgetc (stdin); - clearerr (stdin); - } - while (ans2 != EOF && ans2 != '\n'); - if (answer >= 'a') - answer -= 040; - if (answer == 'Y') - { - retval = 1; - break; - } - if (answer == 'N') - { - retval = 0; - break; - } - printf_filtered ("Please answer y or n.\n"); - } - - if (annotation_level > 1) - printf_filtered ("\n\032\032post-query\n"); - return retval; -} - - -/* Parse a C escape sequence. STRING_PTR points to a variable - containing a pointer to the string to parse. That pointer - should point to the character after the \. That pointer - is updated past the characters we use. The value of the - escape sequence is returned. - - A negative value means the sequence \ newline was seen, - which is supposed to be equivalent to nothing at all. - - If \ is followed by a null character, we return a negative - value and leave the string pointer pointing at the null character. - - If \ is followed by 000, we return 0 and leave the string pointer - after the zeros. A value of 0 does not mean end of string. */ - -int -parse_escape (string_ptr) - char **string_ptr; -{ - register int c = *(*string_ptr)++; - switch (c) - { - case 'a': - return 007; /* Bell (alert) char */ - case 'b': - return '\b'; - case 'e': /* Escape character */ - return 033; - case 'f': - return '\f'; - case 'n': - return '\n'; - case 'r': - return '\r'; - case 't': - return '\t'; - case 'v': - return '\v'; - case '\n': - return -2; - case 0: - (*string_ptr)--; - return 0; - case '^': - c = *(*string_ptr)++; - if (c == '\\') - c = parse_escape (string_ptr); - if (c == '?') - return 0177; - return (c & 0200) | (c & 037); - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - register int i = c - '0'; - register int count = 0; - while (++count < 3) - { - if ((c = *(*string_ptr)++) >= '0' && c <= '7') - { - i *= 8; - i += c - '0'; - } - else - { - (*string_ptr)--; - break; - } - } - return i; - } - default: - return c; - } -} - -/* Print the character C on STREAM as part of the contents of a literal - string whose delimiter is QUOTER. Note that this routine should only - be call for printing things which are independent of the language - of the program being debugged. */ - -void -gdb_printchar (c, stream, quoter) - register int c; - FILE *stream; - int quoter; -{ - - c &= 0xFF; /* Avoid sign bit follies */ - - if ( c < 0x20 || /* Low control chars */ - (c >= 0x7F && c < 0xA0) || /* DEL, High controls */ - (sevenbit_strings && c >= 0x80)) { /* high order bit set */ - switch (c) - { - case '\n': - fputs_filtered ("\\n", stream); - break; - case '\b': - fputs_filtered ("\\b", stream); - break; - case '\t': - fputs_filtered ("\\t", stream); - break; - case '\f': - fputs_filtered ("\\f", stream); - break; - case '\r': - fputs_filtered ("\\r", stream); - break; - case '\033': - fputs_filtered ("\\e", stream); - break; - case '\007': - fputs_filtered ("\\a", stream); - break; - default: - fprintf_filtered (stream, "\\%.3o", (unsigned int) c); - break; - } - } else { - if (c == '\\' || c == quoter) - fputs_filtered ("\\", stream); - fprintf_filtered (stream, "%c", c); - } -} - -/* Number of lines per page or UINT_MAX if paging is disabled. */ -static unsigned int lines_per_page; -/* Number of chars per line or UNIT_MAX is line folding is disabled. */ -static unsigned int chars_per_line; -/* Current count of lines printed on this page, chars on this line. */ -static unsigned int lines_printed, chars_printed; - -/* Buffer and start column of buffered text, for doing smarter word- - wrapping. When someone calls wrap_here(), we start buffering output - that comes through fputs_filtered(). If we see a newline, we just - spit it out and forget about the wrap_here(). If we see another - wrap_here(), we spit it out and remember the newer one. If we see - the end of the line, we spit out a newline, the indent, and then - the buffered output. */ - -/* Malloc'd buffer with chars_per_line+2 bytes. Contains characters which - are waiting to be output (they have already been counted in chars_printed). - When wrap_buffer[0] is null, the buffer is empty. */ -static char *wrap_buffer; - -/* Pointer in wrap_buffer to the next character to fill. */ -static char *wrap_pointer; - -/* String to indent by if the wrap occurs. Must not be NULL if wrap_column - is non-zero. */ -static char *wrap_indent; - -/* Column number on the screen where wrap_buffer begins, or 0 if wrapping - 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; -{ - if (!wrap_buffer) - { - wrap_buffer = (char *) xmalloc (chars_per_line + 2); - wrap_buffer[0] = '\0'; - } - else - wrap_buffer = (char *) xrealloc (wrap_buffer, chars_per_line + 2); - wrap_pointer = wrap_buffer; /* Start it at the beginning */ -} - -/* Wait, so the user can read what's on the screen. Prompt the user - to continue by pressing RETURN. */ - -static void -prompt_for_continue () -{ - char *ignore; - char cont_prompt[120]; - - if (annotation_level > 1) - printf_unfiltered ("\n\032\032pre-prompt-for-continue\n"); - - strcpy (cont_prompt, - "---Type to continue, or q to quit---"); - if (annotation_level > 1) - strcat (cont_prompt, "\n\032\032prompt-for-continue\n"); - - /* We must do this *before* we call gdb_readline, else it will eventually - call us -- thinking that we're trying to print beyond the end of the - screen. */ - reinitialize_more_filter (); - - immediate_quit++; - /* On a real operating system, the user can quit with SIGINT. - But not on GO32. - - 'q' is provided on all systems so users don't have to change habits - from system to system, and because telling them what to do in - the prompt is more user-friendly than expecting them to think of - SIGINT. */ - /* Call readline, not gdb_readline, because GO32 readline handles control-C - whereas control-C to gdb_readline will cause the user to get dumped - out to DOS. */ - ignore = readline (cont_prompt); - - if (annotation_level > 1) - printf_unfiltered ("\n\032\032post-prompt-for-continue\n"); - - if (ignore) - { - char *p = ignore; - while (*p == ' ' || *p == '\t') - ++p; - if (p[0] == 'q') - request_quit (SIGINT); - free (ignore); - } - immediate_quit--; - - /* Now we have to do this again, so that GDB will know that it doesn't - need to save the ---Type --- line at the top of the screen. */ - reinitialize_more_filter (); - - dont_repeat (); /* Forget prev cmd -- CR won't repeat it. */ -} - -/* Reinitialize filter; ie. tell it to reset to original values. */ - -void -reinitialize_more_filter () -{ - lines_printed = 0; - chars_printed = 0; -} - -/* Indicate that if the next sequence of characters overflows the line, - a newline should be inserted here rather than when it hits the end. - If INDENT is non-null, it is a string to be printed to indent the - wrapped part on the next line. INDENT must remain accessible until - the next call to wrap_here() or until a newline is printed through - fputs_filtered(). - - If the line is already overfull, we immediately print a newline and - the indentation, and disable further wrapping. - - If we don't know the width of lines, but we know the page height, - we must not wrap words, but should still keep track of newlines - that were explicitly printed. - - INDENT should not contain tabs, as that will mess up the char count - on the next line. FIXME. - - This routine is guaranteed to force out any output which has been - squirreled away in the wrap_buffer, so wrap_here ((char *)0) can be - used to force out output from the wrap_buffer. */ - -void -wrap_here(indent) - char *indent; -{ - /* This should have been allocated, but be paranoid anyway. */ - if (!wrap_buffer) - abort (); - - if (wrap_buffer[0]) - { - *wrap_pointer = '\0'; - fputs_unfiltered (wrap_buffer, gdb_stdout); - } - wrap_pointer = wrap_buffer; - wrap_buffer[0] = '\0'; - if (chars_per_line == UINT_MAX) /* No line overflow checking */ - { - wrap_column = 0; - } - else if (chars_printed >= chars_per_line) - { - puts_filtered ("\n"); - if (indent != NULL) - puts_filtered (indent); - wrap_column = 0; - } - else - { - wrap_column = chars_printed; - if (indent == NULL) - wrap_indent = ""; - else - wrap_indent = indent; - } -} - -/* Ensure that whatever gets printed next, using the filtered output - commands, starts at the beginning of the line. I.E. if there is - any pending output for the current line, flush it and start a new - line. Otherwise do nothing. */ - -void -begin_line () -{ - if (chars_printed > 0) - { - puts_filtered ("\n"); - } -} - - -GDB_FILE * -gdb_fopen (name, mode) - char * name; - char * mode; -{ - return fopen (name, mode); -} - -void -gdb_flush (stream) - FILE *stream; -{ - fflush (stream); -} - -/* Like fputs but if FILTER is true, pause after every screenful. - - Regardless of FILTER can wrap at points other than the final - character of a line. - - Unlike fputs, fputs_maybe_filtered does not return a value. - It is OK for LINEBUFFER to be NULL, in which case just don't print - anything. - - Note that a longjmp to top level may occur in this routine (only if - FILTER is true) (since prompt_for_continue may do so) so this - routine should not be called when cleanups are not in place. */ - -static void -fputs_maybe_filtered (linebuffer, stream, filter) - const char *linebuffer; - FILE *stream; - int filter; -{ - const char *lineptr; - - if (linebuffer == 0) - return; - - /* Don't do any filtering if it is disabled. */ - if (stream != gdb_stdout - || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)) - { - fputs_unfiltered (linebuffer, stream); - return; - } - - /* Go through and output each character. Show line extension - when this is necessary; prompt user for new page when this is - necessary. */ - - lineptr = linebuffer; - while (*lineptr) - { - /* Possible new page. */ - if (filter && - (lines_printed >= lines_per_page - 1)) - prompt_for_continue (); - - while (*lineptr && *lineptr != '\n') - { - /* Print a single line. */ - if (*lineptr == '\t') - { - if (wrap_column) - *wrap_pointer++ = '\t'; - else - fputc_unfiltered ('\t', stream); - /* Shifting right by 3 produces the number of tab stops - we have already passed, and then adding one and - shifting left 3 advances to the next tab stop. */ - chars_printed = ((chars_printed >> 3) + 1) << 3; - lineptr++; - } - else - { - if (wrap_column) - *wrap_pointer++ = *lineptr; - else - fputc_unfiltered (*lineptr, stream); - chars_printed++; - lineptr++; - } - - if (chars_printed >= chars_per_line) - { - unsigned int save_chars = chars_printed; - - chars_printed = 0; - lines_printed++; - /* If we aren't actually wrapping, don't output newline -- - if chars_per_line is right, we probably just overflowed - anyway; if it's wrong, let us keep going. */ - if (wrap_column) - fputc_unfiltered ('\n', stream); - - /* Possible new page. */ - if (lines_printed >= lines_per_page - 1) - prompt_for_continue (); - - /* Now output indentation and wrapped string */ - if (wrap_column) - { - fputs_unfiltered (wrap_indent, stream); - *wrap_pointer = '\0'; /* Null-terminate saved stuff */ - fputs_unfiltered (wrap_buffer, stream); /* and eject it */ - /* FIXME, this strlen is what prevents wrap_indent from - containing tabs. However, if we recurse to print it - and count its chars, we risk trouble if wrap_indent is - longer than (the user settable) chars_per_line. - Note also that this can set chars_printed > chars_per_line - if we are printing a long string. */ - chars_printed = strlen (wrap_indent) - + (save_chars - wrap_column); - wrap_pointer = wrap_buffer; /* Reset buffer */ - wrap_buffer[0] = '\0'; - wrap_column = 0; /* And disable fancy wrap */ - } - } - } - - if (*lineptr == '\n') - { - chars_printed = 0; - wrap_here ((char *)0); /* Spit out chars, cancel further wraps */ - lines_printed++; - fputc_unfiltered ('\n', stream); - lineptr++; - } - } -} - -void -fputs_filtered (linebuffer, stream) - const char *linebuffer; - FILE *stream; -{ - fputs_maybe_filtered (linebuffer, stream, 1); -} - -void -putc_unfiltered (c) - int c; -{ - char buf[2]; - buf[0] = c; - buf[1] = 0; - fputs_unfiltered (buf, gdb_stdout); -} - -void -fputc_unfiltered (c, stream) - int c; - FILE * stream; -{ - char buf[2]; - buf[0] = c; - buf[1] = 0; - fputs_unfiltered (buf, stream); -} - - -/* Print a variable number of ARGS using format FORMAT. If this - information is going to put the amount written (since the last call - to REINITIALIZE_MORE_FILTER or the last page break) over the page size, - call prompt_for_continue to get the users permision to continue. - - Unlike fprintf, this function does not return a value. - - We implement three variants, vfprintf (takes a vararg list and stream), - fprintf (takes a stream to write on), and printf (the usual). - - Note also that a longjmp to top level may occur in this routine - (since prompt_for_continue may do so) so this routine should not be - called when cleanups are not in place. */ - -static void -vfprintf_maybe_filtered (stream, format, args, filter) - FILE *stream; - char *format; - va_list args; - int filter; -{ - char *linebuffer; - struct cleanup *old_cleanups; - - vasprintf (&linebuffer, format, args); - if (linebuffer == NULL) - { - fputs_unfiltered ("\ngdb: virtual memory exhausted.\n", gdb_stderr); - exit (1); - } - old_cleanups = make_cleanup (free, linebuffer); - fputs_maybe_filtered (linebuffer, stream, filter); - do_cleanups (old_cleanups); -} - - -void -vfprintf_filtered (stream, format, args) - FILE *stream; - char *format; - va_list args; -{ - vfprintf_maybe_filtered (stream, format, args, 1); -} - -void -vfprintf_unfiltered (stream, format, args) - FILE *stream; - char *format; - va_list args; -{ - char *linebuffer; - struct cleanup *old_cleanups; - - vasprintf (&linebuffer, format, args); - if (linebuffer == NULL) - { - fputs_unfiltered ("\ngdb: virtual memory exhausted.\n", gdb_stderr); - exit (1); - } - old_cleanups = make_cleanup (free, linebuffer); - fputs_unfiltered (linebuffer, stream); - do_cleanups (old_cleanups); -} - -void -vprintf_filtered (format, args) - char *format; - va_list args; -{ - vfprintf_maybe_filtered (gdb_stdout, format, args, 1); -} - -void -vprintf_unfiltered (format, args) - char *format; - va_list args; -{ - vfprintf_unfiltered (gdb_stdout, format, args); -} - -/* VARARGS */ -void -fprintf_filtered (va_alist) - va_dcl -{ - va_list args; - FILE *stream; - char *format; - - va_start (args); - stream = va_arg (args, FILE *); - format = va_arg (args, char *); - - vfprintf_filtered (stream, format, args); - va_end (args); -} - -/* VARARGS */ -void -fprintf_unfiltered (va_alist) - va_dcl -{ - va_list args; - FILE *stream; - char *format; - - va_start (args); - stream = va_arg (args, FILE *); - format = va_arg (args, char *); - - vfprintf_unfiltered (stream, format, args); - va_end (args); -} - -/* Like fprintf_filtered, but prints its result indented. - Called as fprintfi_filtered (spaces, stream, format, ...); */ - -/* VARARGS */ -void -fprintfi_filtered (va_alist) - va_dcl -{ - va_list args; - int spaces; - FILE *stream; - char *format; - - va_start (args); - spaces = va_arg (args, int); - stream = va_arg (args, FILE *); - format = va_arg (args, char *); - print_spaces_filtered (spaces, stream); - - vfprintf_filtered (stream, format, args); - va_end (args); -} - - -/* VARARGS */ -void -printf_filtered (va_alist) - va_dcl -{ - va_list args; - char *format; - - va_start (args); - format = va_arg (args, char *); - - vfprintf_filtered (gdb_stdout, format, args); - va_end (args); -} - - -/* VARARGS */ -void -printf_unfiltered (va_alist) - va_dcl -{ - va_list args; - char *format; - - va_start (args); - format = va_arg (args, char *); - - vfprintf_unfiltered (gdb_stdout, format, args); - va_end (args); -} - -/* Like printf_filtered, but prints it's result indented. - Called as printfi_filtered (spaces, format, ...); */ - -/* VARARGS */ -void -printfi_filtered (va_alist) - va_dcl -{ - va_list args; - int spaces; - char *format; - - va_start (args); - spaces = va_arg (args, int); - format = va_arg (args, char *); - print_spaces_filtered (spaces, gdb_stdout); - vfprintf_filtered (gdb_stdout, format, args); - va_end (args); -} - -/* Easy -- but watch out! - - This routine is *not* a replacement for puts()! puts() appends a newline. - This one doesn't, and had better not! */ - -void -puts_filtered (string) - char *string; -{ - fputs_filtered (string, gdb_stdout); -} - -void -puts_unfiltered (string) - char *string; -{ - fputs_unfiltered (string, gdb_stdout); -} - -/* Return a pointer to N spaces and a null. The pointer is good - until the next call to here. */ -char * -n_spaces (n) - int n; -{ - register char *t; - static char *spaces; - static int max_spaces; - - if (n > max_spaces) - { - if (spaces) - free (spaces); - spaces = (char *) xmalloc (n+1); - for (t = spaces+n; t != spaces;) - *--t = ' '; - spaces[n] = '\0'; - max_spaces = n; - } - - return spaces + max_spaces - n; -} - -/* Print N spaces. */ -void -print_spaces_filtered (n, stream) - int n; - FILE *stream; -{ - fputs_filtered (n_spaces (n), stream); -} - -/* C++ demangler stuff. */ - -/* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language - LANG, using demangling args ARG_MODE, and print it filtered to STREAM. - If the name is not mangled, or the language for the name is unknown, or - demangling is off, the name is printed in its "raw" form. */ - -void -fprintf_symbol_filtered (stream, name, lang, arg_mode) - FILE *stream; - char *name; - enum language lang; - int arg_mode; -{ - char *demangled; - - if (name != NULL) - { - /* If user wants to see raw output, no problem. */ - if (!demangle) - { - fputs_filtered (name, stream); - } - else - { - switch (lang) - { - case language_cplus: - demangled = cplus_demangle (name, arg_mode); - break; - case language_chill: - demangled = chill_demangle (name); - break; - default: - demangled = NULL; - break; - } - fputs_filtered (demangled ? demangled : name, stream); - if (demangled != NULL) - { - free (demangled); - } - } - } -} - -/* Do a strcmp() type operation on STRING1 and STRING2, ignoring any - differences in whitespace. Returns 0 if they match, non-zero if they - don't (slightly different than strcmp()'s range of return values). - - As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO". - This "feature" is useful when searching for matching C++ function names - (such as if the user types 'break FOO', where FOO is a mangled C++ - function). */ - -int -strcmp_iw (string1, string2) - const char *string1; - const char *string2; -{ - while ((*string1 != '\0') && (*string2 != '\0')) - { - while (isspace (*string1)) - { - string1++; - } - while (isspace (*string2)) - { - string2++; - } - if (*string1 != *string2) - { - break; - } - if (*string1 != '\0') - { - string1++; - string2++; - } - } - return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0'); -} - - -void -_initialize_utils () -{ - struct cmd_list_element *c; - - c = add_set_cmd ("width", class_support, var_uinteger, - (char *)&chars_per_line, - "Set number of characters gdb thinks are in a line.", - &setlist); - add_show_from_set (c, &showlist); - c->function.sfunc = set_width_command; - - add_show_from_set - (add_set_cmd ("height", class_support, - var_uinteger, (char *)&lines_per_page, - "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__) - lines_per_page = ScreenRows(); - chars_per_line = ScreenCols(); -#else - lines_per_page = 24; - chars_per_line = 80; - /* 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; - - 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; - } - } - } - -#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)) - lines_per_page = UINT_MAX; - - set_width_command ((char *)NULL, 0, c); - - add_show_from_set - (add_set_cmd ("demangle", class_support, var_boolean, - (char *)&demangle, - "Set demangling of encoded C++ names when displaying symbols.", - &setprintlist), - &showprintlist); - - 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.", - &setprintlist), - &showprintlist); - - add_show_from_set - (add_set_cmd ("asm-demangle", class_support, var_boolean, - (char *)&asm_demangle, - "Set demangling of C++ names in disassembly listings.", - &setprintlist), - &showprintlist); -} - -/* Machine specific function to handle SIGWINCH signal. */ - -#ifdef SIGWINCH_HANDLER_BODY - SIGWINCH_HANDLER_BODY -#endif - diff --git a/gnu/usr.bin/gdb/gdb/valarith.c b/gnu/usr.bin/gdb/gdb/valarith.c deleted file mode 100644 index 8a01b46..0000000 --- a/gnu/usr.bin/gdb/gdb/valarith.c +++ /dev/null @@ -1,1068 +0,0 @@ -/* Perform arithmetic and other operations on values, for GDB. - Copyright 1986, 1989, 1991, 1992 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 "defs.h" -#include "value.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" -#include "target.h" -#include "language.h" -#include "demangle.h" -#include - -/* Define whether or not the C operator '/' truncates towards zero for - differently signed operands (truncation direction is undefined in C). */ - -#ifndef TRUNCATION_TOWARDS_ZERO -#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2) -#endif - -static value_ptr value_subscripted_rvalue PARAMS ((value_ptr, value_ptr)); - - -value_ptr -value_add (arg1, arg2) - value_ptr arg1, arg2; -{ - register value_ptr valint, valptr; - register int len; - - COERCE_ARRAY (arg1); - COERCE_ARRAY (arg2); - - if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR - || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR) - && - (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT - || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT)) - /* Exactly one argument is a pointer, and one is an integer. */ - { - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) - { - valptr = arg1; - valint = arg2; - } - else - { - valptr = arg2; - valint = arg1; - } - len = TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (valptr))); - if (len == 0) len = 1; /* For (void *) */ - return value_from_longest (VALUE_TYPE (valptr), - value_as_long (valptr) - + (len * value_as_long (valint))); - } - - return value_binop (arg1, arg2, BINOP_ADD); -} - -value_ptr -value_sub (arg1, arg2) - value_ptr arg1, arg2; -{ - - COERCE_ARRAY (arg1); - COERCE_ARRAY (arg2); - - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) - { - if (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT) - { - /* pointer - integer. */ - return value_from_longest - (VALUE_TYPE (arg1), - value_as_long (arg1) - - (TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) - * value_as_long (arg2))); - } - else if (VALUE_TYPE (arg1) == VALUE_TYPE (arg2)) - { - /* pointer to - pointer to . */ - return value_from_longest - (builtin_type_long, /* FIXME -- should be ptrdiff_t */ - (value_as_long (arg1) - value_as_long (arg2)) - / TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)))); - } - else - { - error ("\ -First argument of `-' is a pointer and second argument is neither\n\ -an integer nor a pointer of the same type."); - } - } - - return value_binop (arg1, arg2, BINOP_SUB); -} - -/* Return the value of ARRAY[IDX]. - See comments in value_coerce_array() for rationale for reason for - doing lower bounds adjustment here rather than there. - FIXME: Perhaps we should validate that the index is valid and if - verbosity is set, warn about invalid indices (but still use them). */ - -value_ptr -value_subscript (array, idx) - value_ptr array, idx; -{ - int lowerbound; - value_ptr bound; - struct type *range_type; - - COERCE_REF (array); - - if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_ARRAY - || TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_STRING) - { - range_type = TYPE_FIELD_TYPE (VALUE_TYPE (array), 0); - lowerbound = TYPE_FIELD_BITPOS (range_type, 0); - if (lowerbound != 0) - { - bound = value_from_longest (builtin_type_int, (LONGEST) lowerbound); - idx = value_sub (idx, bound); - } - if (VALUE_LVAL (array) != lval_memory) - { - return value_subscripted_rvalue (array, idx); - } - array = value_coerce_array (array); - } - return value_ind (value_add (array, idx)); -} - -/* Return the value of EXPR[IDX], expr an aggregate rvalue - (eg, a vector register). This routine used to promote floats - to doubles, but no longer does. */ - -static value_ptr -value_subscripted_rvalue (array, idx) - value_ptr array, idx; -{ - struct type *elt_type = TYPE_TARGET_TYPE (VALUE_TYPE (array)); - int elt_size = TYPE_LENGTH (elt_type); - int elt_offs = elt_size * longest_to_int (value_as_long (idx)); - value_ptr v; - - if (elt_offs >= TYPE_LENGTH (VALUE_TYPE (array))) - error ("no such vector element"); - - v = allocate_value (elt_type); - memcpy (VALUE_CONTENTS (v), VALUE_CONTENTS (array) + elt_offs, elt_size); - - if (VALUE_LVAL (array) == lval_internalvar) - VALUE_LVAL (v) = lval_internalvar_component; - else - VALUE_LVAL (v) = not_lval; - VALUE_ADDRESS (v) = VALUE_ADDRESS (array); - VALUE_OFFSET (v) = VALUE_OFFSET (array) + elt_offs; - VALUE_BITSIZE (v) = elt_size * 8; - return v; -} - -/* Check to see if either argument is a structure. This is called so - we know whether to go ahead with the normal binop or look for a - user defined function instead. - - For now, we do not overload the `=' operator. */ - -int -binop_user_defined_p (op, arg1, arg2) - enum exp_opcode op; - value_ptr arg1, arg2; -{ - if (op == BINOP_ASSIGN) - return 0; - return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT - || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT - || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF - && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT) - || (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_REF - && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_STRUCT)); -} - -/* Check to see if argument is a structure. This is called so - we know whether to go ahead with the normal unop or look for a - user defined function instead. - - For now, we do not overload the `&' operator. */ - -int unop_user_defined_p (op, arg1) - enum exp_opcode op; - value_ptr arg1; -{ - if (op == UNOP_ADDR) - return 0; - return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT - || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF - && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT)); -} - -/* We know either arg1 or arg2 is a structure, so try to find the right - user defined function. Create an argument vector that calls - arg1.operator @ (arg1,arg2) and return that value (where '@' is any - binary operator which is legal for GNU C++). - - OP is the operatore, and if it is BINOP_ASSIGN_MODIFY, then OTHEROP - is the opcode saying how to modify it. Otherwise, OTHEROP is - unused. */ - -value_ptr -value_x_binop (arg1, arg2, op, otherop) - value_ptr arg1, arg2; - enum exp_opcode op, otherop; -{ - value_ptr * argvec; - char *ptr; - char tstr[13]; - int static_memfuncp; - - COERCE_REF (arg1); - COERCE_REF (arg2); - COERCE_ENUM (arg1); - COERCE_ENUM (arg2); - - /* now we know that what we have to do is construct our - arg vector and find the right function to call it with. */ - - if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT) - error ("Can't do that binary op on that type"); /* FIXME be explicit */ - - argvec = (value_ptr *) alloca (sizeof (value_ptr) * 4); - argvec[1] = value_addr (arg1); - argvec[2] = arg2; - argvec[3] = 0; - - /* make the right function name up */ - strcpy(tstr, "operator__"); - ptr = tstr+8; - switch (op) - { - case BINOP_ADD: strcpy(ptr,"+"); break; - case BINOP_SUB: strcpy(ptr,"-"); break; - case BINOP_MUL: strcpy(ptr,"*"); break; - case BINOP_DIV: strcpy(ptr,"/"); break; - case BINOP_REM: strcpy(ptr,"%"); break; - case BINOP_LSH: strcpy(ptr,"<<"); break; - case BINOP_RSH: strcpy(ptr,">>"); break; - case BINOP_BITWISE_AND: strcpy(ptr,"&"); break; - case BINOP_BITWISE_IOR: strcpy(ptr,"|"); break; - case BINOP_BITWISE_XOR: strcpy(ptr,"^"); break; - case BINOP_LOGICAL_AND: strcpy(ptr,"&&"); break; - case BINOP_LOGICAL_OR: strcpy(ptr,"||"); break; - case BINOP_MIN: strcpy(ptr,"?"); break; - case BINOP_ASSIGN: strcpy(ptr,"="); break; - case BINOP_ASSIGN_MODIFY: - switch (otherop) - { - case BINOP_ADD: strcpy(ptr,"+="); break; - case BINOP_SUB: strcpy(ptr,"-="); break; - case BINOP_MUL: strcpy(ptr,"*="); break; - case BINOP_DIV: strcpy(ptr,"/="); break; - case BINOP_REM: strcpy(ptr,"%="); break; - case BINOP_BITWISE_AND: strcpy(ptr,"&="); break; - case BINOP_BITWISE_IOR: strcpy(ptr,"|="); break; - case BINOP_BITWISE_XOR: strcpy(ptr,"^="); break; - case BINOP_MOD: /* invalid */ - default: - error ("Invalid binary operation specified."); - } - break; - case BINOP_SUBSCRIPT: strcpy(ptr,"[]"); break; - case BINOP_EQUAL: strcpy(ptr,"=="); break; - case BINOP_NOTEQUAL: strcpy(ptr,"!="); break; - case BINOP_LESS: strcpy(ptr,"<"); break; - case BINOP_GTR: strcpy(ptr,">"); break; - case BINOP_GEQ: strcpy(ptr,">="); break; - case BINOP_LEQ: strcpy(ptr,"<="); break; - case BINOP_MOD: /* invalid */ - default: - error ("Invalid binary operation specified."); - } - - argvec[0] = value_struct_elt (&arg1, argvec+1, tstr, &static_memfuncp, "structure"); - - if (argvec[0]) - { - if (static_memfuncp) - { - argvec[1] = argvec[0]; - argvec++; - } - return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1); - } - error ("member function %s not found", tstr); -#ifdef lint - return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1); -#endif -} - -/* We know that arg1 is a structure, so try to find a unary user - defined operator that matches the operator in question. - Create an argument vector that calls arg1.operator @ (arg1) - and return that value (where '@' is (almost) any unary operator which - is legal for GNU C++). */ - -value_ptr -value_x_unop (arg1, op) - value_ptr arg1; - enum exp_opcode op; -{ - value_ptr * argvec; - char *ptr, *mangle_ptr; - char tstr[13], mangle_tstr[13]; - int static_memfuncp; - - COERCE_ENUM (arg1); - - /* now we know that what we have to do is construct our - arg vector and find the right function to call it with. */ - - if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT) - error ("Can't do that unary op on that type"); /* FIXME be explicit */ - - argvec = (value_ptr *) alloca (sizeof (value_ptr) * 3); - argvec[1] = value_addr (arg1); - argvec[2] = 0; - - /* make the right function name up */ - strcpy(tstr,"operator__"); - ptr = tstr+8; - strcpy(mangle_tstr, "__"); - mangle_ptr = mangle_tstr+2; - switch (op) - { - case UNOP_PREINCREMENT: strcpy(ptr,"++"); break; - case UNOP_PREDECREMENT: strcpy(ptr,"++"); break; - case UNOP_POSTINCREMENT: strcpy(ptr,"++"); break; - case UNOP_POSTDECREMENT: strcpy(ptr,"++"); break; - case UNOP_LOGICAL_NOT: strcpy(ptr,"!"); break; - case UNOP_COMPLEMENT: strcpy(ptr,"~"); break; - case UNOP_NEG: strcpy(ptr,"-"); break; - default: - error ("Invalid binary operation specified."); - } - - argvec[0] = value_struct_elt (&arg1, argvec+1, tstr, &static_memfuncp, "structure"); - - if (argvec[0]) - { - if (static_memfuncp) - { - argvec[1] = argvec[0]; - argvec++; - } - return call_function_by_hand (argvec[0], 1 - static_memfuncp, argvec + 1); - } - error ("member function %s not found", tstr); - return 0; /* For lint -- never reached */ -} - - -/* Concatenate two values with the following conditions: - - (1) Both values must be either bitstring values or character string - values and the resulting value consists of the concatenation of - ARG1 followed by ARG2. - - or - - One value must be an integer value and the other value must be - either a bitstring value or character string value, which is - to be repeated by the number of times specified by the integer - value. - - - (2) Boolean values are also allowed and are treated as bit string - values of length 1. - - (3) Character values are also allowed and are treated as character - string values of length 1. -*/ - -value_ptr -value_concat (arg1, arg2) - value_ptr arg1, arg2; -{ - register value_ptr inval1, inval2, outval; - int inval1len, inval2len; - int count, idx; - char *ptr; - char inchar; - - /* First figure out if we are dealing with two values to be concatenated - or a repeat count and a value to be repeated. INVAL1 is set to the - first of two concatenated values, or the repeat count. INVAL2 is set - to the second of the two concatenated values or the value to be - repeated. */ - - if (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT) - { - inval1 = arg2; - inval2 = arg1; - } - else - { - inval1 = arg1; - inval2 = arg2; - } - - /* Now process the input values. */ - - if (TYPE_CODE (VALUE_TYPE (inval1)) == TYPE_CODE_INT) - { - /* We have a repeat count. Validate the second value and then - construct a value repeated that many times. */ - if (TYPE_CODE (VALUE_TYPE (inval2)) == TYPE_CODE_STRING - || TYPE_CODE (VALUE_TYPE (inval2)) == TYPE_CODE_CHAR) - { - count = longest_to_int (value_as_long (inval1)); - inval2len = TYPE_LENGTH (VALUE_TYPE (inval2)); - ptr = (char *) alloca (count * inval2len); - if (TYPE_CODE (VALUE_TYPE (inval2)) == TYPE_CODE_CHAR) - { - inchar = (char) unpack_long (VALUE_TYPE (inval2), - VALUE_CONTENTS (inval2)); - for (idx = 0; idx < count; idx++) - { - *(ptr + idx) = inchar; - } - } - else - { - for (idx = 0; idx < count; idx++) - { - memcpy (ptr + (idx * inval2len), VALUE_CONTENTS (inval2), - inval2len); - } - } - outval = value_string (ptr, count * inval2len); - } - else if (TYPE_CODE (VALUE_TYPE (inval2)) == TYPE_CODE_BITSTRING - || TYPE_CODE (VALUE_TYPE (inval2)) == TYPE_CODE_BOOL) - { - error ("unimplemented support for bitstring/boolean repeats"); - } - else - { - error ("can't repeat values of that type"); - } - } - else if (TYPE_CODE (VALUE_TYPE (inval1)) == TYPE_CODE_STRING - || TYPE_CODE (VALUE_TYPE (inval1)) == TYPE_CODE_CHAR) - { - /* We have two character strings to concatenate. */ - if (TYPE_CODE (VALUE_TYPE (inval2)) != TYPE_CODE_STRING - && TYPE_CODE (VALUE_TYPE (inval2)) != TYPE_CODE_CHAR) - { - error ("Strings can only be concatenated with other strings."); - } - inval1len = TYPE_LENGTH (VALUE_TYPE (inval1)); - inval2len = TYPE_LENGTH (VALUE_TYPE (inval2)); - ptr = (char *) alloca (inval1len + inval2len); - if (TYPE_CODE (VALUE_TYPE (inval1)) == TYPE_CODE_CHAR) - { - *ptr = (char) unpack_long (VALUE_TYPE (inval1), VALUE_CONTENTS (inval1)); - } - else - { - memcpy (ptr, VALUE_CONTENTS (inval1), inval1len); - } - if (TYPE_CODE (VALUE_TYPE (inval2)) == TYPE_CODE_CHAR) - { - *(ptr + inval1len) = - (char) unpack_long (VALUE_TYPE (inval2), VALUE_CONTENTS (inval2)); - } - else - { - memcpy (ptr + inval1len, VALUE_CONTENTS (inval2), inval2len); - } - outval = value_string (ptr, inval1len + inval2len); - } - else if (TYPE_CODE (VALUE_TYPE (inval1)) == TYPE_CODE_BITSTRING - || TYPE_CODE (VALUE_TYPE (inval1)) == TYPE_CODE_BOOL) - { - /* We have two bitstrings to concatenate. */ - if (TYPE_CODE (VALUE_TYPE (inval2)) != TYPE_CODE_BITSTRING - && TYPE_CODE (VALUE_TYPE (inval2)) != TYPE_CODE_BOOL) - { - error ("Bitstrings or booleans can only be concatenated with other bitstrings or booleans."); - } - error ("unimplemented support for bitstring/boolean concatenation."); - } - else - { - /* We don't know how to concatenate these operands. */ - error ("illegal operands for concatenation."); - } - return (outval); -} - - - -/* Perform a binary operation on two operands which have reasonable - representations as integers or floats. This includes booleans, - characters, integers, or floats. - Does not support addition and subtraction on pointers; - use value_add or value_sub if you want to handle those possibilities. */ - -value_ptr -value_binop (arg1, arg2, op) - value_ptr arg1, arg2; - enum exp_opcode op; -{ - register value_ptr val; - - COERCE_ENUM (arg1); - COERCE_ENUM (arg2); - - if ((TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_FLT - && TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_CHAR - && TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT - && TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_BOOL - && TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_RANGE) - || - (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_FLT - && TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_CHAR - && TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT - && TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_BOOL - && TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_RANGE)) - error ("Argument to arithmetic operation not a number or boolean."); - - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT - || - TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FLT) - { - /* FIXME-if-picky-about-floating-accuracy: Should be doing this - in target format. real.c in GCC probably has the necessary - code. */ - double v1, v2, v; - v1 = value_as_double (arg1); - v2 = value_as_double (arg2); - switch (op) - { - case BINOP_ADD: - v = v1 + v2; - break; - - case BINOP_SUB: - v = v1 - v2; - break; - - case BINOP_MUL: - v = v1 * v2; - break; - - case BINOP_DIV: - v = v1 / v2; - break; - - default: - error ("Integer-only operation on floating point number."); - } - - val = allocate_value (builtin_type_double); - store_floating (VALUE_CONTENTS_RAW (val), TYPE_LENGTH (VALUE_TYPE (val)), - v); - } - else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_BOOL - && - TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_BOOL) - { - LONGEST v1, v2, v; - v1 = value_as_long (arg1); - v2 = value_as_long (arg2); - - switch (op) - { - case BINOP_BITWISE_AND: - v = v1 & v2; - break; - - case BINOP_BITWISE_IOR: - v = v1 | v2; - break; - - case BINOP_BITWISE_XOR: - v = v1 ^ v2; - break; - - default: - error ("Invalid operation on booleans."); - } - - val = allocate_value (builtin_type_chill_bool); - store_signed_integer (VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (VALUE_TYPE (val)), - v); - } - else - /* Integral operations here. */ - /* FIXME: Also mixed integral/booleans, with result an integer. */ - { - /* Should we promote to unsigned longest? */ - if ((TYPE_UNSIGNED (VALUE_TYPE (arg1)) - || TYPE_UNSIGNED (VALUE_TYPE (arg2))) - && (TYPE_LENGTH (VALUE_TYPE (arg1)) >= sizeof (unsigned LONGEST) - || TYPE_LENGTH (VALUE_TYPE (arg2)) >= sizeof (unsigned LONGEST))) - { - unsigned LONGEST v1, v2, v; - v1 = (unsigned LONGEST) value_as_long (arg1); - v2 = (unsigned LONGEST) value_as_long (arg2); - - switch (op) - { - case BINOP_ADD: - v = v1 + v2; - break; - - case BINOP_SUB: - v = v1 - v2; - break; - - case BINOP_MUL: - v = v1 * v2; - break; - - case BINOP_DIV: - v = v1 / v2; - break; - - case BINOP_REM: - v = v1 % v2; - break; - - case BINOP_MOD: - /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, - v1 mod 0 has a defined value, v1. */ - /* Chill specifies that v2 must be > 0, so check for that. */ - if (current_language -> la_language == language_chill - && value_as_long (arg2) <= 0) - { - error ("Second operand of MOD must be greater than zero."); - } - if (v2 == 0) - { - v = v1; - } - else - { - v = v1/v2; - /* Note floor(v1/v2) == v1/v2 for unsigned. */ - v = v1 - (v2 * v); - } - break; - - case BINOP_LSH: - v = v1 << v2; - break; - - case BINOP_RSH: - v = v1 >> v2; - break; - - case BINOP_BITWISE_AND: - v = v1 & v2; - break; - - case BINOP_BITWISE_IOR: - v = v1 | v2; - break; - - case BINOP_BITWISE_XOR: - v = v1 ^ v2; - break; - - case BINOP_LOGICAL_AND: - v = v1 && v2; - break; - - case BINOP_LOGICAL_OR: - v = v1 || v2; - break; - - case BINOP_MIN: - v = v1 < v2 ? v1 : v2; - break; - - case BINOP_MAX: - v = v1 > v2 ? v1 : v2; - break; - - default: - error ("Invalid binary operation on numbers."); - } - - /* This is a kludge to get around the fact that we don't - know how to determine the result type from the types of - the operands. (I'm not really sure how much we feel the - need to duplicate the exact rules of the current - language. They can get really hairy. But not to do so - makes it hard to document just what we *do* do). */ - - /* Can't just call init_type because we wouldn't know what - name to give the type. */ - val = allocate_value - (sizeof (LONGEST) > TARGET_LONG_BIT / HOST_CHAR_BIT - ? builtin_type_unsigned_long_long - : builtin_type_unsigned_long); - store_unsigned_integer (VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (VALUE_TYPE (val)), - v); - } - else - { - LONGEST v1, v2, v; - v1 = value_as_long (arg1); - v2 = value_as_long (arg2); - - switch (op) - { - case BINOP_ADD: - v = v1 + v2; - break; - - case BINOP_SUB: - v = v1 - v2; - break; - - case BINOP_MUL: - v = v1 * v2; - break; - - case BINOP_DIV: - v = v1 / v2; - break; - - case BINOP_REM: - v = v1 % v2; - break; - - case BINOP_MOD: - /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, - X mod 0 has a defined value, X. */ - /* Chill specifies that v2 must be > 0, so check for that. */ - if (current_language -> la_language == language_chill - && v2 <= 0) - { - error ("Second operand of MOD must be greater than zero."); - } - if (v2 == 0) - { - v = v1; - } - else - { - v = v1/v2; - /* Compute floor. */ - if (TRUNCATION_TOWARDS_ZERO && (v < 0) && ((v1 % v2) != 0)) - { - v--; - } - v = v1 - (v2 * v); - } - break; - - case BINOP_LSH: - v = v1 << v2; - break; - - case BINOP_RSH: - v = v1 >> v2; - break; - - case BINOP_BITWISE_AND: - v = v1 & v2; - break; - - case BINOP_BITWISE_IOR: - v = v1 | v2; - break; - - case BINOP_BITWISE_XOR: - v = v1 ^ v2; - break; - - case BINOP_LOGICAL_AND: - v = v1 && v2; - break; - - case BINOP_LOGICAL_OR: - v = v1 || v2; - break; - - case BINOP_MIN: - v = v1 < v2 ? v1 : v2; - break; - - case BINOP_MAX: - v = v1 > v2 ? v1 : v2; - break; - - default: - error ("Invalid binary operation on numbers."); - } - - /* This is a kludge to get around the fact that we don't - know how to determine the result type from the types of - the operands. (I'm not really sure how much we feel the - need to duplicate the exact rules of the current - language. They can get really hairy. But not to do so - makes it hard to document just what we *do* do). */ - - /* Can't just call init_type because we wouldn't know what - name to give the type. */ - val = allocate_value - (sizeof (LONGEST) > TARGET_LONG_BIT / HOST_CHAR_BIT - ? builtin_type_long_long - : builtin_type_long); - store_signed_integer (VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (VALUE_TYPE (val)), - v); - } - } - - return val; -} - -/* Simulate the C operator ! -- return 1 if ARG1 contains zero. */ - -int -value_logical_not (arg1) - value_ptr arg1; -{ - register int len; - register char *p; - - COERCE_ARRAY (arg1); - - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_FLT) - return 0 == value_as_double (arg1); - - len = TYPE_LENGTH (VALUE_TYPE (arg1)); - p = VALUE_CONTENTS (arg1); - - while (--len >= 0) - { - if (*p++) - break; - } - - return len < 0; -} - -/* Simulate the C operator == by returning a 1 - iff ARG1 and ARG2 have equal contents. */ - -int -value_equal (arg1, arg2) - register value_ptr arg1, arg2; - -{ - register int len; - register char *p1, *p2; - enum type_code code1; - enum type_code code2; - - COERCE_ARRAY (arg1); - COERCE_ARRAY (arg2); - - code1 = TYPE_CODE (VALUE_TYPE (arg1)); - code2 = TYPE_CODE (VALUE_TYPE (arg2)); - - if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT) - return value_as_long (arg1) == value_as_long (arg2); - else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT) - && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT)) - 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) - return value_as_pointer (arg1) == (CORE_ADDR) value_as_long (arg2); - else if (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT) - return (CORE_ADDR) value_as_long (arg1) == value_as_pointer (arg2); - - else if (code1 == code2 - && ((len = TYPE_LENGTH (VALUE_TYPE (arg1))) - == TYPE_LENGTH (VALUE_TYPE (arg2)))) - { - p1 = VALUE_CONTENTS (arg1); - p2 = VALUE_CONTENTS (arg2); - while (--len >= 0) - { - if (*p1++ != *p2++) - break; - } - return len < 0; - } - else - { - error ("Invalid type combination in equality test."); - return 0; /* For lint -- never reached */ - } -} - -/* Simulate the C operator < by returning 1 - iff ARG1's contents are less than ARG2's. */ - -int -value_less (arg1, arg2) - register value_ptr arg1, arg2; -{ - register enum type_code code1; - register enum type_code code2; - - COERCE_ARRAY (arg1); - COERCE_ARRAY (arg2); - - code1 = TYPE_CODE (VALUE_TYPE (arg1)); - code2 = TYPE_CODE (VALUE_TYPE (arg2)); - - if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT) - { - if (TYPE_UNSIGNED (VALUE_TYPE (arg1)) - || TYPE_UNSIGNED (VALUE_TYPE (arg2))) - return ((unsigned LONGEST) value_as_long (arg1) - < (unsigned LONGEST) value_as_long (arg2)); - else - return value_as_long (arg1) < value_as_long (arg2); - } - else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT) - && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT)) - 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) - return value_as_pointer (arg1) < (CORE_ADDR) value_as_long (arg2); - else if (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT) - return (CORE_ADDR) value_as_long (arg1) < value_as_pointer (arg2); - - else - { - error ("Invalid type combination in ordering comparison."); - return 0; - } -} - -/* The unary operators - and ~. Both free the argument ARG1. */ - -value_ptr -value_neg (arg1) - register value_ptr arg1; -{ - register struct type *type; - - COERCE_ENUM (arg1); - - type = 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)); - else { - error ("Argument to negate operation not a number."); - return 0; /* For lint -- never reached */ - } -} - -value_ptr -value_complement (arg1) - register value_ptr arg1; -{ - COERCE_ENUM (arg1); - - if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_INT) - error ("Argument to complement operation not an integer."); - - return value_from_longest (VALUE_TYPE (arg1), ~ value_as_long (arg1)); -} - -/* The INDEX'th bit of SET value whose VALUE_TYPE is TYPE, - and whose VALUE_CONTENTS is valaddr. - Return -1 if out of range, -2 other error. */ - -int -value_bit_index (type, valaddr, index) - struct type *type; - char *valaddr; - int index; -{ - struct type *range; - int low_bound, high_bound, bit_length; - LONGEST word; - range = TYPE_FIELD_TYPE (type, 0); - if (TYPE_CODE (range) != TYPE_CODE_RANGE) - return -2; - low_bound = TYPE_LOW_BOUND (range); - high_bound = TYPE_HIGH_BOUND (range); - if (index < low_bound || index > high_bound) - return -1; - bit_length = high_bound - low_bound + 1; - index -= low_bound; - if (bit_length <= TARGET_CHAR_BIT) - word = unpack_long (builtin_type_unsigned_char, valaddr); - else if (bit_length <= TARGET_SHORT_BIT) - word = unpack_long (builtin_type_unsigned_short, valaddr); - else - { - int word_start_index = (index / TARGET_INT_BIT) * TARGET_INT_BIT; - index -= word_start_index; - word = unpack_long (builtin_type_unsigned_int, - valaddr + (word_start_index / HOST_CHAR_BIT)); - } -#if BITS_BIG_ENDIAN - if (bit_length <= TARGET_CHAR_BIT) - index = TARGET_CHAR_BIT - 1 - index; - else if (bit_length <= TARGET_SHORT_BIT) - index = TARGET_SHORT_BIT - 1 - index; - else - index = TARGET_INT_BIT - 1 - index; -#endif - return (word >> index) & 1; -} - -value_ptr -value_in (element, set) - value_ptr element, set; -{ - int member; - if (TYPE_CODE (VALUE_TYPE (set)) != TYPE_CODE_SET) - error ("Second argument of 'IN' has wrong type"); - if (TYPE_CODE (VALUE_TYPE (element)) != TYPE_CODE_INT - && TYPE_CODE (VALUE_TYPE (element)) != TYPE_CODE_CHAR - && TYPE_CODE (VALUE_TYPE (element)) != TYPE_CODE_ENUM - && TYPE_CODE (VALUE_TYPE (element)) != TYPE_CODE_BOOL) - error ("First argument of 'IN' has wrong type"); - member = value_bit_index (VALUE_TYPE (set), VALUE_CONTENTS (set), - value_as_long (element)); - if (member < 0) - error ("First argument of 'IN' not in range"); - return value_from_longest (builtin_type_int, member); -} - -void -_initialize_valarith () -{ -} diff --git a/gnu/usr.bin/gdb/gdb/valops.c b/gnu/usr.bin/gdb/gdb/valops.c deleted file mode 100644 index f84db12..0000000 --- a/gnu/usr.bin/gdb/gdb/valops.c +++ /dev/null @@ -1,1898 +0,0 @@ -/* Perform non-arithmetic operations on values, for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "value.h" -#include "frame.h" -#include "inferior.h" -#include "gdbcore.h" -#include "target.h" -#include "demangle.h" -#include "language.h" - -#include - -/* Local functions. */ - -static int typecmp PARAMS ((int staticp, struct type *t1[], value_ptr t2[])); - -static CORE_ADDR find_function_addr PARAMS ((value_ptr, struct type **)); - -static CORE_ADDR value_push PARAMS ((CORE_ADDR, value_ptr)); - -static CORE_ADDR value_arg_push PARAMS ((CORE_ADDR, value_ptr)); - -static value_ptr search_struct_field PARAMS ((char *, value_ptr, int, - struct type *, int)); - -static value_ptr search_struct_method PARAMS ((char *, value_ptr *, - value_ptr *, - int, int *, struct type *)); - -static int -check_field_in PARAMS ((struct type *, const char *)); - -static CORE_ADDR -allocate_space_in_inferior PARAMS ((int)); - - -/* Allocate NBYTES of space in the inferior using the inferior's malloc - and return a value that is a pointer to the allocated space. */ - -static CORE_ADDR -allocate_space_in_inferior (len) - int len; -{ - register value_ptr val; - register struct symbol *sym; - struct minimal_symbol *msymbol; - struct type *type; - value_ptr blocklen; - LONGEST maddr; - - /* Find the address of malloc in the inferior. */ - - sym = lookup_symbol ("malloc", 0, VAR_NAMESPACE, 0, NULL); - if (sym != NULL) - { - if (SYMBOL_CLASS (sym) != LOC_BLOCK) - { - error ("\"malloc\" exists in this program but is not a function."); - } - val = value_of_variable (sym, NULL); - } - else - { - msymbol = lookup_minimal_symbol ("malloc", (struct objfile *) NULL); - if (msymbol != NULL) - { - type = lookup_pointer_type (builtin_type_char); - type = lookup_function_type (type); - type = lookup_pointer_type (type); - maddr = (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol); - val = value_from_longest (type, maddr); - } - else - { - error ("evaluation of this expression requires the program to have a function \"malloc\"."); - } - } - - blocklen = value_from_longest (builtin_type_int, (LONGEST) len); - val = call_function_by_hand (val, 1, &blocklen); - if (value_logical_not (val)) - { - error ("No memory available to program."); - } - return (value_as_long (val)); -} - -/* Cast value ARG2 to type TYPE and return as a value. - More general than a C cast: accepts any two types of the same length, - and if ARG2 is an lvalue it can be cast into anything at all. */ -/* In C++, casts may change pointer or object representations. */ - -value_ptr -value_cast (type, arg2) - struct type *type; - register value_ptr arg2; -{ - register enum type_code code1; - register enum type_code code2; - register int scalar; - - /* Coerce arrays but not enums. Enums will work as-is - and coercing them would cause an infinite recursion. */ - if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_ENUM) - COERCE_ARRAY (arg2); - - code1 = TYPE_CODE (type); - code2 = TYPE_CODE (VALUE_TYPE (arg2)); - scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT - || code2 == TYPE_CODE_ENUM); - - if ( code1 == TYPE_CODE_STRUCT - && code2 == TYPE_CODE_STRUCT - && TYPE_NAME (type) != 0) - { - /* 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 object in addition to changing its type. */ - value_ptr v = search_struct_field (type_name_no_tag (type), - arg2, 0, VALUE_TYPE (arg2), 1); - if (v) - { - VALUE_TYPE (v) = type; - return v; - } - } - if (code1 == TYPE_CODE_FLT && scalar) - return value_from_double (type, value_as_double (arg2)); - else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM) - && (scalar || code2 == TYPE_CODE_PTR)) - return value_from_longest (type, value_as_long (arg2)); - else if (TYPE_LENGTH (type) == TYPE_LENGTH (VALUE_TYPE (arg2))) - { - 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 = TYPE_TARGET_TYPE (type); - struct type *t2 = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)); - 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_ptr 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; - } - } - /* No superclass found, just fall through to change ptr type. */ - } - VALUE_TYPE (arg2) = type; - return arg2; - } - else if (VALUE_LVAL (arg2) == lval_memory) - { - return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2)); - } - else if (code1 == TYPE_CODE_VOID) - { - return value_zero (builtin_type_void, not_lval); - } - else - { - error ("Invalid cast."); - return 0; - } -} - -/* Create a value of type TYPE that is zero, and return it. */ - -value_ptr -value_zero (type, lv) - struct type *type; - enum lval_type lv; -{ - register value_ptr val = allocate_value (type); - - memset (VALUE_CONTENTS (val), 0, TYPE_LENGTH (type)); - VALUE_LVAL (val) = lv; - - return val; -} - -/* Return a value with type TYPE located at ADDR. - - Call value_at only if the data needs to be fetched immediately; - if we can be 'lazy' and defer the fetch, perhaps indefinately, call - 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. */ - -value_ptr -value_at (type, addr) - struct type *type; - CORE_ADDR addr; -{ - register value_ptr val; - - if (TYPE_CODE (type) == TYPE_CODE_VOID) - error ("Attempt to dereference a generic pointer."); - - val = allocate_value (type); - - read_memory (addr, VALUE_CONTENTS_RAW (val), TYPE_LENGTH (type)); - - VALUE_LVAL (val) = lval_memory; - VALUE_ADDRESS (val) = addr; - - return val; -} - -/* Return a lazy value with type TYPE located at ADDR (cf. value_at). */ - -value_ptr -value_at_lazy (type, addr) - struct type *type; - CORE_ADDR addr; -{ - register value_ptr val; - - if (TYPE_CODE (type) == TYPE_CODE_VOID) - error ("Attempt to dereference a generic pointer."); - - val = allocate_value (type); - - VALUE_LVAL (val) = lval_memory; - VALUE_ADDRESS (val) = addr; - VALUE_LAZY (val) = 1; - - 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. - - 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. - - This function returns a value because it is used in the VALUE_CONTENTS - macro as part of an expression, where a void would not work. The - value is ignored. */ - -int -value_fetch_lazy (val) - register value_ptr val; -{ - CORE_ADDR addr = VALUE_ADDRESS (val) + VALUE_OFFSET (val); - - if (TYPE_LENGTH (VALUE_TYPE (val))) - read_memory (addr, VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (VALUE_TYPE (val))); - VALUE_LAZY (val) = 0; - return 0; -} - - -/* Store the contents of FROMVAL into the location of TOVAL. - Return a new value with the location of TOVAL and contents of FROMVAL. */ - -value_ptr -value_assign (toval, fromval) - register value_ptr toval, fromval; -{ - register struct type *type; - register value_ptr val; - char raw_buffer[MAX_REGISTER_RAW_SIZE]; - int use_buffer = 0; - - if (!toval->modifiable) - error ("Left operand of assignment is not a modifiable lvalue."); - - COERCE_ARRAY (fromval); - COERCE_REF (toval); - - type = VALUE_TYPE (toval); - if (VALUE_LVAL (toval) != lval_internalvar) - fromval = value_cast (type, fromval); - - /* If TOVAL is a special machine register requiring conversion - of program values to a special raw format, - convert FROMVAL's contents now, with result in `raw_buffer', - and set USE_BUFFER to the number of bytes to write. */ - -#ifdef REGISTER_CONVERTIBLE - if (VALUE_REGNO (toval) >= 0 - && REGISTER_CONVERTIBLE (VALUE_REGNO (toval))) - { - int regno = VALUE_REGNO (toval); - if (REGISTER_CONVERTIBLE (regno)) - { - REGISTER_CONVERT_TO_RAW (VALUE_TYPE (fromval), regno, - VALUE_CONTENTS (fromval), raw_buffer); - use_buffer = REGISTER_RAW_SIZE (regno); - } - } -#endif - - switch (VALUE_LVAL (toval)) - { - case lval_internalvar: - set_internalvar (VALUE_INTERNALVAR (toval), fromval); - break; - - case lval_internalvar_component: - set_internalvar_component (VALUE_INTERNALVAR (toval), - VALUE_OFFSET (toval), - VALUE_BITPOS (toval), - VALUE_BITSIZE (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) - + VALUE_BITSIZE (toval) - + HOST_CHAR_BIT - 1) - / HOST_CHAR_BIT; - - if (len > 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)); - break; - - case lval_register: - if (VALUE_BITSIZE (toval)) - { - char buffer[sizeof (LONGEST)]; - int len = REGISTER_RAW_SIZE (VALUE_REGNO (toval)); - - if (len > sizeof (LONGEST)) - error ("Can't handle bitfields in registers larger than %d bits.", - sizeof (LONGEST) * HOST_CHAR_BIT); - - if (VALUE_BITPOS (toval) + VALUE_BITSIZE (toval) - > len * HOST_CHAR_BIT) - /* Getting this right would involve being very careful about - byte order. */ - error ("\ -Can't handle bitfield which doesn't fit in a single register."); - - read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - buffer, len); - modify_field (buffer, value_as_long (fromval), - VALUE_BITPOS (toval), VALUE_BITSIZE (toval)); - write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - buffer, len); - } - else if (use_buffer) - write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - raw_buffer, use_buffer); - else - { - /* Do any conversion necessary when storing this type to more - than one register. */ -#ifdef REGISTER_CONVERT_FROM_TYPE - memcpy (raw_buffer, VALUE_CONTENTS (fromval), TYPE_LENGTH (type)); - REGISTER_CONVERT_FROM_TYPE(VALUE_REGNO (toval), type, raw_buffer); - write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - raw_buffer, TYPE_LENGTH (type)); -#else - write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval), - VALUE_CONTENTS (fromval), TYPE_LENGTH (type)); -#endif - } - /* Assigning to the stack pointer, frame pointer, and other - (architecture and calling convention specific) registers may - cause the frame cache to be out of date. We just do this - on all assignments to registers for simplicity; I doubt the slowdown - matters. */ - reinit_frame_cache (); - break; - - case lval_reg_frame_relative: - { - /* value is stored in a series of registers in the frame - specified by the structure. Copy that value out, modify - it, and copy it back in. */ - int amount_to_copy = (VALUE_BITSIZE (toval) ? 1 : TYPE_LENGTH (type)); - int reg_size = REGISTER_RAW_SIZE (VALUE_FRAME_REGNUM (toval)); - int byte_offset = VALUE_OFFSET (toval) % reg_size; - int reg_offset = VALUE_OFFSET (toval) / reg_size; - int amount_copied; - - /* Make the buffer large enough in all cases. */ - char *buffer = (char *) alloca (amount_to_copy - + sizeof (LONGEST) - + MAX_REGISTER_RAW_SIZE); - - int regno; - FRAME frame; - - /* Figure out which frame this is in currently. */ - for (frame = get_current_frame (); - frame && FRAME_FP (frame) != VALUE_FRAME (toval); - frame = get_prev_frame (frame)) - ; - - if (!frame) - error ("Value being assigned to is no longer active."); - - amount_to_copy += (reg_size - amount_to_copy % reg_size); - - /* Copy it out. */ - for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset, - amount_copied = 0); - amount_copied < amount_to_copy; - amount_copied += reg_size, regno++) - { - get_saved_register (buffer + amount_copied, - (int *)NULL, (CORE_ADDR *)NULL, - frame, regno, (enum lval_type *)NULL); - } - - /* Modify what needs to be modified. */ - if (VALUE_BITSIZE (toval)) - modify_field (buffer + byte_offset, - value_as_long (fromval), - VALUE_BITPOS (toval), VALUE_BITSIZE (toval)); - else if (use_buffer) - memcpy (buffer + byte_offset, raw_buffer, use_buffer); - else - memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval), - TYPE_LENGTH (type)); - - /* Copy it back. */ - for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset, - amount_copied = 0); - amount_copied < amount_to_copy; - amount_copied += reg_size, regno++) - { - enum lval_type lval; - CORE_ADDR addr; - int optim; - - /* Just find out where to put it. */ - get_saved_register ((char *)NULL, - &optim, &addr, frame, regno, &lval); - - if (optim) - error ("Attempt to assign to a value that was optimized out."); - if (lval == lval_memory) - write_memory (addr, buffer + amount_copied, reg_size); - else if (lval == lval_register) - write_register_bytes (addr, buffer + amount_copied, reg_size); - else - error ("Attempt to assign to an unmodifiable value."); - } - } - break; - - - default: - error ("Left operand of assignment is not an lvalue."); - } - - /* Return a value just like TOVAL except with the contents of FROMVAL - (except in the case of the type if TOVAL is an internalvar). */ - - if (VALUE_LVAL (toval) == lval_internalvar - || VALUE_LVAL (toval) == lval_internalvar_component) - { - type = VALUE_TYPE (fromval); - } - - val = allocate_value (type); - memcpy (val, toval, VALUE_CONTENTS_RAW (val) - (char *) val); - memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval), - TYPE_LENGTH (type)); - VALUE_TYPE (val) = type; - - return val; -} - -/* Extend a value VAL to COUNT repetitions of its type. */ - -value_ptr -value_repeat (arg1, count) - value_ptr arg1; - int count; -{ - register value_ptr val; - - if (VALUE_LVAL (arg1) != lval_memory) - error ("Only values in memory can be extended with '@'."); - if (count < 1) - error ("Invalid number %d of repetitions.", count); - - val = allocate_repeat_value (VALUE_TYPE (arg1), count); - - read_memory (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1), - VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (VALUE_TYPE (val)) * count); - VALUE_LVAL (val) = lval_memory; - VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1); - - return val; -} - -value_ptr -value_of_variable (var, b) - struct symbol *var; - struct block *b; -{ - value_ptr val; - FRAME fr; - - if (b == NULL) - /* Use selected frame. */ - fr = NULL; - else - { - fr = block_innermost_frame (b); - if (fr == NULL && symbol_read_needs_frame (var)) - { - if (BLOCK_FUNCTION (b) != NULL - && SYMBOL_NAME (BLOCK_FUNCTION (b)) != NULL) - error ("No frame is currently executing in block %s.", - SYMBOL_NAME (BLOCK_FUNCTION (b))); - else - error ("No frame is currently executing in specified block"); - } - } - val = read_var_value (var, fr); - if (val == 0) - error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var)); - return val; -} - -/* Given a value which is an array, return a value which is a pointer to its - first element, regardless of whether or not the array has a nonzero lower - bound. - - FIXME: A previous comment here indicated that this routine should be - substracting the array's lower bound. It's not clear to me that this - is correct. Given an array subscripting operation, it would certainly - work to do the adjustment here, essentially computing: - - (&array[0] - (lowerbound * sizeof array[0])) + (index * sizeof array[0]) - - However I believe a more appropriate and logical place to account for - the lower bound is to do so in value_subscript, essentially computing: - - (&array[0] + ((index - lowerbound) * sizeof array[0])) - - As further evidence consider what would happen with operations other - than array subscripting, where the caller would get back a value that - had an address somewhere before the actual first element of the array, - and the information about the lower bound would be lost because of - the coercion to pointer type. - */ - -value_ptr -value_coerce_array (arg1) - value_ptr arg1; -{ - register struct type *type; - - if (VALUE_LVAL (arg1) != lval_memory) - error ("Attempt to take address of value not located in memory."); - - /* Get type of elements. */ - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_ARRAY - || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRING) - type = TYPE_TARGET_TYPE (VALUE_TYPE (arg1)); - else - /* A phony array made by value_repeat. - Its type is the type of the elements, not an array type. */ - type = VALUE_TYPE (arg1); - - return value_from_longest (lookup_pointer_type (type), - (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); -} - -/* Given a value which is a function, return a value which is a pointer - to it. */ - -value_ptr -value_coerce_function (arg1) - value_ptr 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))); -} - -/* Return a pointer value for the object for which ARG1 is the contents. */ - -value_ptr -value_addr (arg1) - value_ptr arg1; -{ - struct type *type = 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); - VALUE_TYPE (arg2) = lookup_pointer_type (TYPE_TARGET_TYPE (type)); - return arg2; - } - if (VALUE_REPEATED (arg1) - || TYPE_CODE (type) == TYPE_CODE_ARRAY) - return value_coerce_array (arg1); - if (TYPE_CODE (type) == TYPE_CODE_FUNC) - return value_coerce_function (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 (type), - (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); -} - -/* Given a value of a pointer type, apply the C unary * operator to it. */ - -value_ptr -value_ind (arg1) - value_ptr arg1; -{ - COERCE_ARRAY (arg1); - - if (TYPE_CODE (VALUE_TYPE (arg1)) == 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 (VALUE_TYPE (arg1)) == TYPE_CODE_INT) - return value_at (builtin_type_int, - (CORE_ADDR) value_as_long (arg1)); - else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) - return value_at_lazy (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)), - value_as_pointer (arg1)); - error ("Attempt to take contents of a non-pointer value."); - return 0; /* For lint -- never reached */ -} - -/* Pushing small parts of stack frames. */ - -/* Push one word (the size of object that a register holds). */ - -CORE_ADDR -push_word (sp, word) - CORE_ADDR sp; - unsigned LONGEST 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 */ - - return sp; -} - -/* Push LEN bytes with data at BUFFER. */ - -CORE_ADDR -push_bytes (sp, buffer, len) - CORE_ADDR sp; - 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 */ - - return sp; -} - -/* Push onto the stack the specified value VALUE. */ - -static CORE_ADDR -value_push (sp, arg) - register CORE_ADDR sp; - value_ptr arg; -{ - register int len = TYPE_LENGTH (VALUE_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 */ - - return sp; -} - -/* Perform the standard coercions that are specified - for arguments to be passed to C functions. */ - -value_ptr -value_arg_coerce (arg) - value_ptr arg; -{ - register struct type *type; - - /* FIXME: We should coerce this according to the prototype (if we have - one). Right now we do a little bit of this in typecmp(), but that - doesn't always get called. For example, if passing a ref to a function - without a prototype, we probably should de-reference it. Currently - we don't. */ - - if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ENUM) - arg = value_cast (builtin_type_unsigned_int, arg); - -#if 1 /* FIXME: This is only a temporary patch. -fnf */ - if (VALUE_REPEATED (arg) - || TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY) - arg = value_coerce_array (arg); - if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FUNC) - arg = value_coerce_function (arg); -#endif - - type = VALUE_TYPE (arg); - - if (TYPE_CODE (type) == TYPE_CODE_INT - && TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) - return value_cast (builtin_type_int, arg); - - if (TYPE_CODE (type) == TYPE_CODE_FLT - && TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double)) - return value_cast (builtin_type_double, arg); - - return arg; -} - -/* Push the value ARG, first coercing it as an argument - to a C function. */ - -static CORE_ADDR -value_arg_push (sp, arg) - register CORE_ADDR sp; - value_ptr arg; -{ - return value_push (sp, value_arg_coerce (arg)); -} - -/* Determine a function's address and its return type from its value. - Calls error() if the function is not valid for calling. */ - -static CORE_ADDR -find_function_addr (function, retval_type) - value_ptr function; - struct type **retval_type; -{ - register struct type *ftype = VALUE_TYPE (function); - register enum type_code code = TYPE_CODE (ftype); - struct type *value_type; - CORE_ADDR funaddr; - - /* If it's a member function, just look at the function - part of it. */ - - /* Determine address to call. */ - if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD) - { - funaddr = VALUE_ADDRESS (function); - value_type = TYPE_TARGET_TYPE (ftype); - } - else if (code == TYPE_CODE_PTR) - { - funaddr = value_as_pointer (function); - if (TYPE_CODE (TYPE_TARGET_TYPE (ftype)) == TYPE_CODE_FUNC - || TYPE_CODE (TYPE_TARGET_TYPE (ftype)) == TYPE_CODE_METHOD) - value_type = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype)); - else - value_type = builtin_type_int; - } - else if (code == TYPE_CODE_INT) - { - /* Handle the case of functions lacking debugging info. - Their values are characters since their addresses are char */ - if (TYPE_LENGTH (ftype) == 1) - funaddr = value_as_pointer (value_addr (function)); - else - /* Handle integer used as address of a function. */ - funaddr = (CORE_ADDR) value_as_long (function); - - value_type = builtin_type_int; - } - else - error ("Invalid data type for function to be called."); - - *retval_type = value_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 - function and then hit a breakpoint (get a signal, etc), "backtrace" - will look right. Whether the backtrace needs to actually show the - stack at the time the inferior function was called is debatable, but - it certainly needs to not display garbage. So if you are contemplating - making dummy frames be different from normal frames, consider that. */ - -/* Perform a function call in the inferior. - ARGS is a vector of values of arguments (NARGS of them). - FUNCTION is a value, the function to be called. - Returns a value representing what the function returned. - May fail to return, if a breakpoint or signal is hit - during the execution of the function. */ - -value_ptr -call_function_by_hand (function, nargs, args) - value_ptr function; - int nargs; - value_ptr *args; -{ - register CORE_ADDR sp; - register int i; - 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)]; - CORE_ADDR old_sp; - struct type *value_type; - unsigned char struct_return; - CORE_ADDR struct_addr; - struct inferior_status inf_status; - struct cleanup *old_chain; - CORE_ADDR funaddr; - int using_gcc; - CORE_ADDR real_pc; - - if (!target_has_execution) - noprocess(); - - save_inferior_status (&inf_status, 1); - old_chain = make_cleanup (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) - they are saved on the stack in the inferior. */ - PUSH_DUMMY_FRAME; - - old_sp = sp = read_sp (); - -#if 1 INNER_THAN 2 /* Stack grows down */ - sp -= sizeof dummy; - start_sp = sp; -#else /* Stack grows up */ - start_sp = sp; - sp += sizeof dummy; -#endif - - funaddr = find_function_addr (function, &value_type); - - { - struct block *b = block_for_pc (funaddr); - /* If compiled without -g, assume GCC. */ - using_gcc = b == NULL || BLOCK_GCC_COMPILED (b); - } - - /* Are we returning a value using a structure return or a normal - value return? */ - - struct_return = using_struct_return (function, funaddr, value_type, - using_gcc); - - /* Create a call sequence customized for this function - and the number of arguments for it. */ - for (i = 0; i < sizeof dummy / sizeof (dummy[0]); i++) - store_unsigned_integer (&dummy1[i * REGISTER_SIZE], - REGISTER_SIZE, - (unsigned LONGEST)dummy[i]); - -#ifdef GDB_TARGET_IS_HPPA - real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args, - value_type, using_gcc); -#else - FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args, - value_type, using_gcc); - real_pc = start_sp; -#endif - -#if CALL_DUMMY_LOCATION == ON_STACK - write_memory (start_sp, (char *)dummy1, sizeof dummy); -#endif /* On stack. */ - -#if CALL_DUMMY_LOCATION == BEFORE_TEXT_END - /* Convex Unix prohibits executing in the stack segment. */ - /* Hope there is empty room at the top of the text segment. */ - { - extern CORE_ADDR text_end; - static checked = 0; - if (!checked) - for (start_sp = text_end - sizeof dummy; start_sp < text_end; ++start_sp) - if (read_memory_integer (start_sp, 1) != 0) - error ("text segment full -- no place to put call"); - checked = 1; - sp = old_sp; - real_pc = text_end - sizeof dummy; - write_memory (real_pc, (char *)dummy1, sizeof dummy); - } -#endif /* Before text_end. */ - -#if CALL_DUMMY_LOCATION == AFTER_TEXT_END - { - extern CORE_ADDR text_end; - int errcode; - sp = old_sp; - real_pc = text_end; - errcode = target_write_memory (real_pc, (char *)dummy1, sizeof dummy); - if (errcode != 0) - error ("Cannot write text segment -- call_function failed"); - } -#endif /* After text_end. */ - -#if CALL_DUMMY_LOCATION == AT_ENTRY_POINT - real_pc = funaddr; -#endif /* At entry point. */ - -#ifdef lint - sp = old_sp; /* It really is used, for some ifdef's... */ -#endif - -#ifdef STACK_ALIGN - /* If stack grows down, we must leave a hole at the top. */ - { - int len = 0; - - /* Reserve space for the return structure to be written on the - stack, if necessary */ - - if (struct_return) - len += TYPE_LENGTH (value_type); - - for (i = nargs - 1; i >= 0; i--) - len += TYPE_LENGTH (VALUE_TYPE (value_arg_coerce (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; -#endif - } -#endif /* STACK_ALIGN */ - - /* Reserve space for the return structure to be written on the - stack, if necessary */ - - if (struct_return) - { -#if 1 INNER_THAN 2 - sp -= TYPE_LENGTH (value_type); - struct_addr = sp; -#else - struct_addr = sp; - sp += TYPE_LENGTH (value_type); -#endif - } - -#if defined (REG_STRUCT_HAS_ADDR) - { - /* This is a machine like the sparc, where we may need to pass a pointer - to the structure, not the structure itself. */ - for (i = nargs - 1; i >= 0; i--) - if (TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT - && REG_STRUCT_HAS_ADDR (using_gcc, VALUE_TYPE (args[i]))) - { - CORE_ADDR addr; -#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; -#endif - /* Push the structure. */ - sp = value_push (sp, args[i]); -#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; -#endif - /* 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), - (LONGEST) addr); - } - } -#endif /* REG_STRUCT_HAS_ADDR. */ - -#ifdef PUSH_ARGUMENTS - PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr); -#else /* !PUSH_ARGUMENTS */ - for (i = nargs - 1; i >= 0; i--) - sp = value_arg_push (sp, args[i]); -#endif /* !PUSH_ARGUMENTS */ - -#ifdef CALL_DUMMY_STACK_ADJUST -#if 1 INNER_THAN 2 - sp -= CALL_DUMMY_STACK_ADJUST; -#else - sp += CALL_DUMMY_STACK_ADJUST; -#endif -#endif /* CALL_DUMMY_STACK_ADJUST */ - - /* Store the address at which the structure is supposed to be - written. Note that this (and the code which reserved the space - above) assumes that gcc was used to compile this function. Since - it doesn't cost us anything but space and if the function is pcc - it will ignore this value, we will make that assumption. - - Also note that on some machines (like the sparc) pcc uses a - convention like gcc's. */ - - if (struct_return) - STORE_STRUCT_RETURN (struct_addr, sp); - - /* Write the stack pointer. This is here because the statements above - might fool with it. On SPARC, this write also stores the register - window into the right place in the new stack frame, which otherwise - wouldn't happen. (See store_inferior_registers in sparc-nat.c.) */ - write_sp (sp); - - { - char retbuf[REGISTER_BYTES]; - char *name; - struct symbol *symbol; - - name = NULL; - symbol = find_pc_function (funaddr); - if (symbol) - { - name = SYMBOL_SOURCE_NAME (symbol); - } - else - { - /* Try the minimal symbols. */ - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr); - - if (msymbol) - { - name = SYMBOL_SOURCE_NAME (msymbol); - } - } - if (name == NULL) - { - char format[80]; - sprintf (format, "at %s", local_hex_format ()); - name = alloca (80); - /* FIXME-32x64: assumes funaddr fits in a long. */ - sprintf (name, format, (unsigned long) funaddr); - } - - /* Execute the stack dummy routine, calling FUNCTION. - When it is done, discard the empty frame - after storing the contents of all regs into retbuf. */ - if (run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf)) - { - /* We stopped somewhere besides the call dummy. */ - - /* If we did the cleanups, we would print a spurious error message - (Unable to restore previously selected frame), would write the - registers from the inf_status (which is wrong), and would do other - wrong things (like set stop_bpstat to the wrong thing). */ - discard_cleanups (old_chain); - /* Prevent memory leak. */ - bpstat_clear (&inf_status.stop_bpstat); - - /* The following error message used to say "The expression - which contained the function call has been discarded." It - is a hard concept to explain in a few words. Ideally, GDB - would be able to resume evaluation of the expression when - the function finally is done executing. Perhaps someday - this will be implemented (it would not be easy). */ - - /* FIXME: Insert a bunch of wrap_here; name can be very long if it's - a C++ name with arguments and stuff. */ - error ("\ -The program being debugged stopped while in a function called from GDB.\n\ -When the function (%s) is done executing, GDB will silently\n\ -stop (instead of continuing to evaluate the expression containing\n\ -the function call).", name); - } - - do_cleanups (old_chain); - - /* Figure out the value returned by the function. */ - return value_being_returned (value_type, retbuf, struct_return); - } -} -#else /* no CALL_DUMMY. */ -value_ptr -call_function_by_hand (function, nargs, args) - value_ptr function; - int nargs; - value_ptr *args; -{ - error ("Cannot invoke functions on this machine."); -} -#endif /* no CALL_DUMMY. */ - - -/* Create a value for an array by allocating space in the inferior, copying - the data into that space, and then setting up an array value. - - The array bounds are set from LOWBOUND and HIGHBOUND, and the array is - populated from the values passed in ELEMVEC. - - The element type of the array is inherited from the type of the - first element, and all elements must have the same size (though we - don't currently enforce any restriction on their types). */ - -value_ptr -value_array (lowbound, highbound, elemvec) - int lowbound; - int highbound; - value_ptr *elemvec; -{ - int nelem; - int idx; - int typelength; - value_ptr val; - struct type *rangetype; - struct type *arraytype; - CORE_ADDR addr; - - /* Validate that the bounds are reasonable and that each of the elements - have the same size. */ - - nelem = highbound - lowbound + 1; - if (nelem <= 0) - { - error ("bad array bounds (%d, %d)", lowbound, highbound); - } - typelength = TYPE_LENGTH (VALUE_TYPE (elemvec[0])); - for (idx = 0; idx < nelem; idx++) - { - if (TYPE_LENGTH (VALUE_TYPE (elemvec[idx])) != typelength) - { - error ("array elements must all be the same size"); - } - } - - /* Allocate space to store the array in the inferior, and then initialize - it by copying in each element. FIXME: Is it worth it to create a - local buffer in which to collect each value and then write all the - bytes in one operation? */ - - addr = allocate_space_in_inferior (nelem * typelength); - for (idx = 0; idx < nelem; idx++) - { - write_memory (addr + (idx * typelength), VALUE_CONTENTS (elemvec[idx]), - typelength); - } - - /* Create the array type and set up an array value to be evaluated lazily. */ - - rangetype = create_range_type ((struct type *) NULL, builtin_type_int, - lowbound, highbound); - arraytype = create_array_type ((struct type *) NULL, - VALUE_TYPE (elemvec[0]), rangetype); - val = value_at_lazy (arraytype, addr); - return (val); -} - -/* Create a value for a string constant by allocating space in the inferior, - copying the data into that space, and returning the address with type - TYPE_CODE_STRING. PTR points to the string constant data; LEN is number - of characters. - Note that string types are like array of char types with a lower bound of - zero and an upper bound of LEN - 1. Also note that the string may contain - embedded null bytes. */ - -value_ptr -value_string (ptr, len) - char *ptr; - int len; -{ - value_ptr val; - struct type *rangetype; - struct type *stringtype; - CORE_ADDR addr; - - /* Allocate space to store the string in the inferior, and then - copy LEN bytes from PTR in gdb to that address in the inferior. */ - - addr = allocate_space_in_inferior (len); - write_memory (addr, ptr, len); - - /* Create the string type and set up a string value to be evaluated - lazily. */ - - rangetype = create_range_type ((struct type *) NULL, builtin_type_int, - 0, len - 1); - stringtype = create_string_type ((struct type *) NULL, rangetype); - val = value_at_lazy (stringtype, addr); - return (val); -} - -/* See if we can pass arguments in T2 to a function which takes arguments - of types T1. Both t1 and t2 are NULL-terminated vectors. If some - arguments need coercion of some sort, then the coerced values are written - into T2. Return value is 0 if the arguments could be matched, or the - position at which they differ if not. - - STATICP is nonzero if the T1 argument list came from a - static member function. - - For non-static member functions, we ignore the first argument, - which is the type of the instance variable. This is because we want - to handle calls with objects from derived classes. This is not - entirely correct: we should actually check to make sure that a - requested operation is type secure, shouldn't we? FIXME. */ - -static int -typecmp (staticp, t1, t2) - int staticp; - struct type *t1[]; - value_ptr t2[]; -{ - int i; - - if (t2 == 0) - return 1; - if (staticp && t1 == 0) - return t2[1] != 0; - if (t1 == 0) - return 1; - if (TYPE_CODE (t1[0]) == TYPE_CODE_VOID) return 0; - if (t1[!staticp] == 0) return 0; - for (i = !staticp; t1[i] && TYPE_CODE (t1[i]) != TYPE_CODE_VOID; i++) - { - struct type *tt1, *tt2; - if (! t2[i]) - return i+1; - tt1 = t1[i]; - tt2 = VALUE_TYPE(t2[i]); - if (TYPE_CODE (tt1) == TYPE_CODE_REF - /* We should be doing hairy argument matching, as below. */ - && (TYPE_CODE (TYPE_TARGET_TYPE (tt1)) == TYPE_CODE (tt2))) - { - t2[i] = value_addr (t2[i]); - continue; - } - - while (TYPE_CODE (tt1) == TYPE_CODE_PTR - && (TYPE_CODE(tt2)==TYPE_CODE_ARRAY || TYPE_CODE(tt2)==TYPE_CODE_PTR)) - { - tt1 = TYPE_TARGET_TYPE(tt1); - tt2 = TYPE_TARGET_TYPE(tt2); - } - if (TYPE_CODE(tt1) == TYPE_CODE(tt2)) continue; - /* Array to pointer is a `trivial conversion' according to the ARM. */ - - /* We should be doing much hairier argument matching (see section 13.2 - of the ARM), but as a quick kludge, just check for the same type - code. */ - if (TYPE_CODE (t1[i]) != TYPE_CODE (VALUE_TYPE (t2[i]))) - return i+1; - } - if (!t1[i]) return 0; - return t2[i] ? i+1 : 0; -} - -/* 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. - If found, return value, else return NULL. - - If LOOKING_FOR_BASECLASS, then instead of looking for struct fields, - look for a baseclass named NAME. */ - -static value_ptr -search_struct_field (name, arg1, offset, type, looking_for_baseclass) - char *name; - register value_ptr arg1; - int offset; - register struct type *type; - int looking_for_baseclass; -{ - int i; - - check_stub_type (type); - - if (! looking_for_baseclass) - for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) - { - char *t_field_name = TYPE_FIELD_NAME (type, i); - - if (t_field_name && STREQ (t_field_name, name)) - { - 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)); - } - else - v = value_primitive_field (arg1, offset, i, type); - if (v == 0) - error("there is no field named %s", name); - return v; - } - } - - for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) - { - value_ptr v; - /* If we are looking for baseclasses, this is what we get when we - hit them. But it could happen that the base part's member name - is not yet filled in. */ - int found_baseclass = (looking_for_baseclass - && TYPE_BASECLASS_NAME (type, i) != NULL - && STREQ (name, TYPE_BASECLASS_NAME (type, i))); - - if (BASETYPE_VIA_VIRTUAL (type, i)) - { - value_ptr v2; - /* Fix to use baseclass_offset instead. FIXME */ - baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset, - &v2, (int *)NULL); - if (v2 == 0) - error ("virtual baseclass botch"); - if (found_baseclass) - return v2; - v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i), - looking_for_baseclass); - } - else if (found_baseclass) - v = value_primitive_field (arg1, offset, i, type); - else - v = search_struct_field (name, arg1, - offset + TYPE_BASECLASS_BITPOS (type, i) / 8, - TYPE_BASECLASS (type, i), - looking_for_baseclass); - if (v) return v; - } - return NULL; -} - -/* 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. - If found, return value, else if name matched and args not return (value)-1, - else return NULL. */ - -static value_ptr -search_struct_method (name, arg1p, args, offset, static_memfuncp, type) - char *name; - register value_ptr *arg1p, *args; - int offset, *static_memfuncp; - register struct type *type; -{ - int i; - value_ptr v; - int name_matched = 0; - char dem_opname[64]; - - check_stub_type (type); - for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--) - { - char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i); - if (strncmp(t_field_name, "__", 2)==0 || - strncmp(t_field_name, "op", 2)==0 || - strncmp(t_field_name, "type", 4)==0 ) - { - if (cplus_demangle_opname(t_field_name, dem_opname, DMGL_ANSI)) - t_field_name = dem_opname; - else if (cplus_demangle_opname(t_field_name, dem_opname, 0)) - t_field_name = dem_opname; - } - if (t_field_name && STREQ (t_field_name, name)) - { - int j = TYPE_FN_FIELDLIST_LENGTH (type, i) - 1; - struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); - name_matched = 1; - - if (j > 0 && args == 0) - error ("cannot resolve overloaded method `%s'", name); - while (j >= 0) - { - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (type, i, j); - if (!typecmp (TYPE_FN_FIELD_STATIC_P (f, j), - TYPE_FN_FIELD_ARGS (f, j), args)) - { - if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) - return value_virtual_fn_field (arg1p, f, j, type, offset); - if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp) - *static_memfuncp = 1; - v = value_fn_field (arg1p, f, j, type, offset); - if (v != NULL) return v; - } - j--; - } - } - } - - for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) - { - int base_offset; - - if (BASETYPE_VIA_VIRTUAL (type, i)) - { - base_offset = baseclass_offset (type, i, *arg1p, offset); - if (base_offset == -1) - error ("virtual baseclass botch"); - } - else - { - base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8; - } - v = search_struct_method (name, arg1p, args, base_offset + offset, - static_memfuncp, TYPE_BASECLASS (type, i)); - if (v == (value_ptr) -1) - { - name_matched = 1; - } - else if (v) - { -/* FIXME-bothner: Why is this commented out? Why is it here? */ -/* *arg1p = arg1_tmp;*/ - return v; - } - } - if (name_matched) return (value_ptr) -1; - else return NULL; -} - -/* Given *ARGP, a value of type (pointer to a)* structure/union, - extract the component named NAME from the ultimate target structure/union - and return it as a value with its appropriate type. - ERR is used in the error message if *ARGP's type is wrong. - - C++: ARGS is a list of argument types to aid in the selection of - an appropriate method. Also, handle derived types. - - STATIC_MEMFUNCP, if non-NULL, points to a caller-supplied location - where the truthvalue of whether the function that was resolved was - a static member function or not is stored. - - ERR is an error message to be printed in case the field is not found. */ - -value_ptr -value_struct_elt (argp, args, name, static_memfuncp, err) - register value_ptr *argp, *args; - char *name; - int *static_memfuncp; - char *err; -{ - register struct type *t; - value_ptr v; - - COERCE_ARRAY (*argp); - - t = VALUE_TYPE (*argp); - - /* Follow pointers until we get to a non-pointer. */ - - 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 = VALUE_TYPE (*argp); - } - - if (TYPE_CODE (t) == TYPE_CODE_MEMBER) - error ("not implemented: member type in value_struct_elt"); - - 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 %s.", err); - - /* Assume it's not, unless we see that it is. */ - if (static_memfuncp) - *static_memfuncp =0; - - if (!args) - { - /* if there are no arguments ...do this... */ - - /* Try as a field first, because if we succeed, there - is less work to be done. */ - v = search_struct_field (name, *argp, 0, t, 0); - if (v) - return v; - - /* C++: If it was not found as a data field, then try to - return it as a pointer to a method. */ - - if (destructor_name_p (name, t)) - error ("Cannot get value of destructor"); - - v = search_struct_method (name, argp, args, 0, static_memfuncp, t); - - if (v == (value_ptr) -1) - error ("Cannot take address of a method"); - else if (v == 0) - { - if (TYPE_NFN_FIELDS (t)) - error ("There is no member or method named %s.", name); - else - error ("There is no member named %s.", name); - } - return v; - } - - if (destructor_name_p (name, t)) - { - 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; - } - else - { - error ("destructor should not have any argument"); - } - } - else - v = search_struct_method (name, argp, args, 0, static_memfuncp, t); - - if (v == (value_ptr) -1) - { - error("Argument list of %s mismatch with component in the structure.", name); - } - else if (v == 0) - { - /* See if user tried to invoke data as function. If so, - hand it back. If it's not callable (i.e., a pointer to function), - gdb should give an error. */ - v = search_struct_field (name, *argp, 0, t, 0); - } - - if (!v) - error ("Structure has no component named %s.", name); - return v; -} - -/* 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. */ -int -destructor_name_p (name, type) - const char *name; - const struct type *type; -{ - /* destructors are a special case. */ - - if (name[0] == '~') - { - char *dname = type_name_no_tag (type); - if (!STREQ (dname, name+1)) - error ("name of destructor must equal name of class"); - else - return 1; - } - return 0; -} - -/* Helper function for check_field: Given TYPE, a structure/union, - return 1 if the component named NAME from the ultimate - target structure/union is defined, otherwise, return 0. */ - -static int -check_field_in (type, name) - register struct type *type; - const char *name; -{ - register int i; - - for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) - { - char *t_field_name = TYPE_FIELD_NAME (type, i); - if (t_field_name && STREQ (t_field_name, name)) - return 1; - } - - /* C++: If it was not found as a data field, then try to - return it as a pointer to a method. */ - - /* Destructors are a special case. */ - if (destructor_name_p (name, type)) - return 1; - - for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i) - { - if (STREQ (TYPE_FN_FIELDLIST_NAME (type, i), name)) - return 1; - } - - for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) - if (check_field_in (TYPE_BASECLASS (type, i), name)) - return 1; - - return 0; -} - - -/* C++: Given ARG1, a value of type (pointer to a)* structure/union, - return 1 if the component named NAME from the ultimate - target structure/union is defined, otherwise, return 0. */ - -int -check_field (arg1, name) - register value_ptr arg1; - const char *name; -{ - register struct type *t; - - COERCE_ARRAY (arg1); - - t = VALUE_TYPE (arg1); - - /* Follow pointers until we get to a non-pointer. */ - - while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF) - t = TYPE_TARGET_TYPE (t); - - if (TYPE_CODE (t) == TYPE_CODE_MEMBER) - error ("not implemented: member type in check_field"); - - if ( TYPE_CODE (t) != TYPE_CODE_STRUCT - && TYPE_CODE (t) != TYPE_CODE_UNION) - error ("Internal error: `this' is not an aggregate"); - - return check_field_in (t, name); -} - -/* C++: Given an aggregate type CURTYPE, and a member name NAME, - return the address of this member as a "pointer to member" - type. If INTYPE is non-null, then it will be the type - of the member we are looking for. This will help us resolve - "pointers to member functions". This function is used - to resolve user expressions of the form "DOMAIN::NAME". */ - -value_ptr -value_struct_elt_for_reference (domain, offset, curtype, name, intype) - struct type *domain, *curtype, *intype; - int offset; - char *name; -{ - register struct type *t = curtype; - register int i; - value_ptr v; - - if ( TYPE_CODE (t) != TYPE_CODE_STRUCT - && TYPE_CODE (t) != TYPE_CODE_UNION) - error ("Internal error: non-aggregate type to value_struct_elt_for_reference"); - - for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--) - { - char *t_field_name = TYPE_FIELD_NAME (t, i); - - if (t_field_name && STREQ (t_field_name, name)) - { - 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)); - } - if (TYPE_FIELD_PACKED (t, i)) - error ("pointers to bitfield members not allowed"); - - return value_from_longest - (lookup_reference_type (lookup_member_type (TYPE_FIELD_TYPE (t, i), - domain)), - offset + (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3)); - } - } - - /* C++: If it was not found as a data field, then try to - return it as a pointer to a method. */ - - /* Destructors are a special case. */ - if (destructor_name_p (name, t)) - { - error ("member pointers to destructors not implemented yet"); - } - - /* Perform all necessary dereferencing. */ - while (intype && TYPE_CODE (intype) == TYPE_CODE_PTR) - intype = TYPE_TARGET_TYPE (intype); - - for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i) - { - char *t_field_name = TYPE_FN_FIELDLIST_NAME (t, i); - char dem_opname[64]; - - if (strncmp(t_field_name, "__", 2)==0 || - strncmp(t_field_name, "op", 2)==0 || - strncmp(t_field_name, "type", 4)==0 ) - { - if (cplus_demangle_opname(t_field_name, dem_opname, DMGL_ANSI)) - t_field_name = dem_opname; - else if (cplus_demangle_opname(t_field_name, dem_opname, 0)) - t_field_name = dem_opname; - } - if (t_field_name && STREQ (t_field_name, name)) - { - int j = TYPE_FN_FIELDLIST_LENGTH (t, i); - struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i); - - if (intype == 0 && j > 1) - error ("non-unique member `%s' requires type instantiation", name); - if (intype) - { - while (j--) - if (TYPE_FN_FIELD_TYPE (f, j) == intype) - break; - if (j < 0) - error ("no member function matches that type instantiation"); - } - else - j = 0; - - if (TYPE_FN_FIELD_STUB (f, j)) - check_stub_method (t, i, j); - if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) - { - return value_from_longest - (lookup_reference_type - (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), - domain)), - (LONGEST) METHOD_PTR_FROM_VOFFSET - (TYPE_FN_FIELD_VOFFSET (f, j))); - } - else - { - struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j), - 0, VAR_NAMESPACE, 0, NULL); - if (s == NULL) - { - v = 0; - } - else - { - v = read_var_value (s, 0); -#if 0 - VALUE_TYPE (v) = lookup_reference_type - (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), - domain)); -#endif - } - return v; - } - } - } - for (i = TYPE_N_BASECLASSES (t) - 1; i >= 0; i--) - { - value_ptr v; - int base_offset; - - if (BASETYPE_VIA_VIRTUAL (t, i)) - base_offset = 0; - else - base_offset = TYPE_BASECLASS_BITPOS (t, i) / 8; - v = value_struct_elt_for_reference (domain, - offset + base_offset, - TYPE_BASECLASS (t, i), - name, - intype); - if (v) - return v; - } - return 0; -} - -/* 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. */ -value_ptr -value_of_this (complain) - int complain; -{ - extern FRAME selected_frame; - struct symbol *func, *sym; - struct block *b; - int i; - static const char funny_this[] = "this"; - value_ptr this; - - if (selected_frame == 0) - if (complain) - error ("no frame selected"); - else return 0; - - func = get_frame_function (selected_frame); - if (!func) - { - if (complain) - error ("no `this' in nameless context"); - else return 0; - } - - b = SYMBOL_BLOCK_VALUE (func); - i = BLOCK_NSYMS (b); - if (i <= 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). */ - sym = lookup_block_symbol (b, funny_this, VAR_NAMESPACE); - if (sym == NULL) - { - if (complain) - error ("current stack frame not in method"); - else - return NULL; - } - - this = read_var_value (sym, selected_frame); - if (this == 0 && complain) - error ("`this' argument at unknown address"); - return this; -} diff --git a/gnu/usr.bin/gdb/gdb/valprint.c b/gnu/usr.bin/gdb/gdb/valprint.c deleted file mode 100644 index 823a8c4..0000000 --- a/gnu/usr.bin/gdb/gdb/valprint.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* Print values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 1992, 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. */ - -#include "defs.h" -#include -#include "symtab.h" -#include "gdbtypes.h" -#include "value.h" -#include "gdbcore.h" -#include "gdbcmd.h" -#include "target.h" -#include "obstack.h" -#include "language.h" -#include "demangle.h" -#include "annotate.h" - -#include - -/* Prototypes for local functions */ - -static void -print_hex_chars PARAMS ((GDB_FILE *, unsigned char *, unsigned int)); - -static void -show_print PARAMS ((char *, int)); - -static void -set_print PARAMS ((char *, int)); - -static void -set_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_1 PARAMS ((int, unsigned)); - -static void -set_output_radix PARAMS ((char *, int, struct cmd_list_element *)); - -static void -set_output_radix_1 PARAMS ((int, unsigned)); - -/* 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" - stores UINT_MAX in print_max, which displays in a show command as - "unlimited". */ - -unsigned int print_max; -#define PRINT_MAX_DEFAULT 200 /* Start print_max off at this value. */ - -/* Default input and output radixes, and output format letter. */ - -unsigned input_radix = 10; -unsigned output_radix = 10; -int output_format = 0; - -/* Print repeat counts if there are more than this many repetitions of an - element in an array. Referenced by the low level language dependent - print routines. */ - -unsigned int repeat_count_threshold = 10; - -/* If nonzero, stops printing of char arrays at first null. */ - -int stop_print_at_null; - -/* Controls pretty printing of structures. */ - -int prettyprint_structs; - -/* Controls pretty printing of arrays. */ - -int prettyprint_arrays; - -/* If nonzero, causes unions inside structures or other unions to be - printed. */ - -int unionprint; /* Controls printing of nested unions. */ - -/* If nonzero, causes machine addresses to be printed in certain contexts. */ - -int addressprint; /* Controls printing of machine addresses */ - - -/* 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 using TYPE). - - If DEREF_REF is nonzero, then dereference references, otherwise just print - them like pointers. - - The PRETTY parameter controls prettyprinting. - - If the data are a string pointer, returns the number of string characters - printed. - - FIXME: The data at VALADDR is in target byte order. If gdb is ever - enhanced to be able to debug more than the single target it was compiled - for (specific CPU type and thus specific target byte ordering), then - either the print routines are going to have to take this into account, - or the data is going to have to be passed into here already converted - to the host byte ordering, whichever is more convenient. */ - - -int -val_print (type, valaddr, 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; -{ - if (pretty == Val_pretty_default) - { - pretty = prettyprint_structs ? Val_prettyprint : Val_no_prettyprint; - } - - QUIT; - - /* Ensure that the type is complete and not just a stub. If the type is - only a stub and we can't find and substitute its complete type, then - print appropriate string and return. */ - - check_stub_type (type); - if (TYPE_FLAGS (type) & TYPE_FLAG_STUB) - { - fprintf_filtered (stream, ""); - gdb_flush (stream); - return (0); - } - - return (LA_VAL_PRINT (type, valaddr, address, stream, format, deref_ref, - recurse, pretty)); -} - -/* Print the value VAL in C-ish syntax on stream STREAM. - FORMAT is a format-letter, or 0 for print in natural format of data type. - If the object printed is a string pointer, returns - the number of string bytes printed. */ - -int -value_print (val, stream, format, pretty) - value_ptr val; - GDB_FILE *stream; - int format; - enum val_prettyprint pretty; -{ - if (val == 0) - { - printf_filtered ("
"); - return 0; - } - if (VALUE_OPTIMIZED_OUT (val)) - { - printf_filtered (""); - return 0; - } - return LA_VALUE_PRINT (val, stream, format, pretty); -} - -/* Called by various _val_print routines to print TYPE_CODE_INT's */ - -void -val_print_type_code_int (type, valaddr, stream) - struct type *type; - char *valaddr; - GDB_FILE *stream; -{ - char *p; - /* Pointer to first (i.e. lowest address) nonzero character. */ - char *first_addr; - unsigned int len; - - if (TYPE_LENGTH (type) > sizeof (LONGEST)) - { - if (TYPE_UNSIGNED (type)) - { - /* First figure out whether the number in fact has zeros - in all its bytes more significant than least significant - sizeof (LONGEST) ones. */ - len = TYPE_LENGTH (type); - -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (p = valaddr; - len > sizeof (LONGEST) && p < valaddr + TYPE_LENGTH (type); - p++) -#else /* Little endian. */ - first_addr = valaddr; - for (p = valaddr + TYPE_LENGTH (type) - 1; - len > sizeof (LONGEST) && p >= valaddr; - p--) -#endif /* Little endian. */ - { - if (*p == 0) - { - len--; - } - else - { - break; - } - } -#if TARGET_BYTE_ORDER == BIG_ENDIAN - first_addr = p; -#endif - if (len <= sizeof (LONGEST)) - { - /* The most significant bytes are zero, so we can just get - the least significant sizeof (LONGEST) bytes and print it - in decimal. */ - print_longest (stream, 'u', 0, - extract_unsigned_integer (first_addr, - sizeof (LONGEST))); - } - else - { - /* It is big, so print it in hex. */ - print_hex_chars (stream, (unsigned char *) first_addr, len); - } - } - else - { - /* Signed. One could assume two's complement (a reasonable - assumption, I think) and do better than this. */ - print_hex_chars (stream, (unsigned char *) valaddr, - TYPE_LENGTH (type)); - } - } - else - { -#ifdef PRINT_TYPELESS_INTEGER - PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr)); -#else - print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, - unpack_long (type, valaddr)); -#endif - } -} - -/* 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). */ - -void -print_longest (stream, format, use_local, val_long) - GDB_FILE *stream; - int format; - int use_local; - 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)) - { - fprintf_filtered (stream, "0x%lx%08lx", vtop, vbot); - return; - } -#endif - -#ifdef PRINTF_HAS_LONG_LONG - switch (format) - { - case 'd': - fprintf_filtered (stream, - use_local ? local_decimal_format_custom ("ll") - : "%lld", - val_long); - break; - case 'u': - fprintf_filtered (stream, "%llu", val_long); - break; - case 'x': - fprintf_filtered (stream, - use_local ? local_hex_format_custom ("ll") - : "%llx", - val_long); - break; - case 'o': - fprintf_filtered (stream, - use_local ? local_octal_format_custom ("ll") - : "%llo", - break; - case 'b': - fprintf_filtered (stream, local_hex_format_custom ("02ll"), val_long); - break; - case 'h': - fprintf_filtered (stream, local_hex_format_custom ("04ll"), val_long); - break; - case 'w': - fprintf_filtered (stream, local_hex_format_custom ("08ll"), val_long); - break; - case 'g': - fprintf_filtered (stream, 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': - fprintf_filtered (stream, - use_local ? local_decimal_format_custom ("l") - : "%ld", - (long) val_long); - break; - case 'u': - fprintf_filtered (stream, "%lu", (unsigned long) val_long); - break; - case 'x': - fprintf_filtered (stream, - use_local ? local_hex_format_custom ("l") - : "%lx", - (long) val_long); - break; - case 'o': - fprintf_filtered (stream, - use_local ? local_octal_format_custom ("l") - : "%lo", - (long) val_long); - break; - case 'b': - fprintf_filtered (stream, local_hex_format_custom ("02l"), - (long) val_long); - break; - case 'h': - fprintf_filtered (stream, local_hex_format_custom ("04l"), - (long) val_long); - break; - case 'w': - fprintf_filtered (stream, local_hex_format_custom ("08l"), - (long) val_long); - break; - case 'g': - fprintf_filtered (stream, local_hex_format_custom ("016l"), - (long) val_long); - break; - default: - abort (); - } -#endif /* !PRINTF_HAS_LONG_LONG */ -} - -/* This used to be a macro, but I don't think it is called often enough - to merit such treatment. */ -/* 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. */ - -int -longest_to_int (arg) - LONGEST 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; -} - -/* Print a floating point value of type TYPE, pointed to in GDB by VALADDR, - on STREAM. */ - -void -print_floating (valaddr, type, stream) - char *valaddr; - struct type *type; - GDB_FILE *stream; -{ - double doub; - int inv; - unsigned len = TYPE_LENGTH (type); - -#if defined (IEEE_FLOAT) - - /* Check for NaN's. Note that this code does not depend on us being - on an IEEE conforming system. It only depends on the target - machine using IEEE representation. This means (a) - cross-debugging works right, and (2) IEEE_FLOAT can (and should) - be defined for systems like the 68881, which uses IEEE - representation, but is not IEEE conforming. */ - - { - unsigned long low, high; - /* Is the sign bit 0? */ - int nonnegative; - /* Is it is a NaN (i.e. the exponent is all ones and - the fraction is nonzero)? */ - int is_nan; - - if (len == 4) - { - /* It's single precision. */ - /* Assume that floating point byte order is the same as - integer byte order. */ - low = extract_unsigned_integer (valaddr, 4); - nonnegative = ((low & 0x80000000) == 0); - is_nan = ((((low >> 23) & 0xFF) == 0xFF) - && 0 != (low & 0x7FFFFF)); - low &= 0x7fffff; - high = 0; - } - else if (len == 8) - { - /* It's double precision. Get the high and low words. */ - - /* Assume that floating point byte order is the same as - integer byte order. */ -#if TARGET_BYTE_ORDER == BIG_ENDIAN - low = extract_unsigned_integer (valaddr + 4, 4); - high = extract_unsigned_integer (valaddr, 4); -#else - low = extract_unsigned_integer (valaddr, 4); - high = extract_unsigned_integer (valaddr + 4, 4); -#endif - nonnegative = ((high & 0x80000000) == 0); - is_nan = (((high >> 20) & 0x7ff) == 0x7ff - && ! ((((high & 0xfffff) == 0)) && (low == 0))); - high &= 0xfffff; - } - else - /* Extended. We can't detect NaNs for extendeds yet. Also note - that currently extendeds get nuked to double in - REGISTER_CONVERTIBLE. */ - is_nan = 0; - - if (is_nan) - { - /* The meaning of the sign and fraction is not defined by IEEE. - But the user might know what they mean. For example, they - (in an implementation-defined manner) distinguish between - signaling and quiet NaN's. */ - if (high) - fprintf_filtered (stream, "-NaN(0x%lx%.8lx)" + nonnegative, - high, low); - else - fprintf_filtered (stream, "-NaN(0x%lx)" + nonnegative, low); - return; - } - } -#endif /* IEEE_FLOAT. */ - - doub = unpack_double (type, valaddr, &inv); - if (inv) - fprintf_filtered (stream, ""); - else - fprintf_filtered (stream, len <= sizeof(float) ? "%.9g" : "%.17g", doub); -} - -/* VALADDR points to an integer of LEN bytes. Print it in hex on stream. */ - -static void -print_hex_chars (stream, valaddr, len) - GDB_FILE *stream; - unsigned char *valaddr; - unsigned len; -{ - unsigned char *p; - - /* FIXME: We should be not printing leading zeroes in most cases. */ - - fprintf_filtered (stream, local_hex_format_prefix ()); -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (p = valaddr; - p < valaddr + len; - p++) -#else /* Little endian. */ - for (p = valaddr + len - 1; - p >= valaddr; - p--) -#endif - { - fprintf_filtered (stream, "%02x", *p); - } - fprintf_filtered (stream, local_hex_format_suffix ()); -} - -/* Called by various _val_print routines to print elements of an - array in the form ", , , ...". - - (FIXME?) Assumes array element separator is a comma, which is correct - for all languages currently handled. - (FIXME?) Some languages have a notation for repeated array elements, - perhaps we should try to use that notation when appropriate. - */ - -void -val_print_array_elements (type, valaddr, address, stream, format, deref_ref, - recurse, pretty, i) - struct type *type; - char *valaddr; - CORE_ADDR address; - GDB_FILE *stream; - int format; - int deref_ref; - int recurse; - enum val_prettyprint pretty; - unsigned int i; -{ - unsigned int things_printed = 0; - unsigned len; - struct type *elttype; - unsigned eltlen; - /* Position of the array element we are examining to see - whether it is repeated. */ - unsigned int rep1; - /* Number of repetitions we have detected so far. */ - unsigned int reps; - - elttype = TYPE_TARGET_TYPE (type); - eltlen = TYPE_LENGTH (elttype); - len = TYPE_LENGTH (type) / eltlen; - - annotate_array_section_begin (i, elttype); - - for (; i < len && things_printed < print_max; i++) - { - if (i != 0) - { - if (prettyprint_arrays) - { - fprintf_filtered (stream, ",\n"); - print_spaces_filtered (2 + 2 * recurse, stream); - } - else - { - fprintf_filtered (stream, ", "); - } - } - wrap_here (n_spaces (2 + 2 * recurse)); - - rep1 = i + 1; - reps = 1; - while ((rep1 < len) && - !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen)) - { - ++reps; - ++rep1; - } - - if (reps > repeat_count_threshold) - { - val_print (elttype, valaddr + i * eltlen, 0, stream, format, - deref_ref, recurse + 1, pretty); - annotate_elt_rep (reps); - fprintf_filtered (stream, " ", reps); - annotate_elt_rep_end (); - - i = rep1 - 1; - things_printed += repeat_count_threshold; - } - else - { - val_print (elttype, valaddr + i * eltlen, 0, stream, format, - deref_ref, recurse + 1, pretty); - annotate_elt (); - things_printed++; - } - } - annotate_array_section_end (); - if (i < len) - { - fprintf_filtered (stream, "..."); - } -} - -void -value_print_array_elements (val, stream, format, pretty) - value_ptr val; - GDB_FILE *stream; - int format; - enum val_prettyprint pretty; -{ - unsigned int things_printed = 0; - register unsigned int i, n, typelen; - /* Position of the array elem we are examining to see if it is repeated. */ - unsigned int rep1; - /* Number of repetitions we have detected so far. */ - unsigned int reps; - - n = VALUE_REPETITIONS (val); - typelen = TYPE_LENGTH (VALUE_TYPE (val)); - for (i = 0; i < n && things_printed < print_max; i++) - { - if (i != 0) - { - fprintf_filtered (stream, ", "); - } - wrap_here (""); - - rep1 = i + 1; - reps = 1; - while (rep1 < n && !memcmp (VALUE_CONTENTS (val) + typelen * i, - VALUE_CONTENTS (val) + typelen * rep1, - typelen)) - { - ++reps; - ++rep1; - } - - if (reps > repeat_count_threshold) - { - val_print (VALUE_TYPE (val), VALUE_CONTENTS (val) + typelen * i, - VALUE_ADDRESS (val) + typelen * i, stream, format, 1, - 0, pretty); - fprintf_unfiltered (stream, " ", reps); - i = rep1 - 1; - things_printed += repeat_count_threshold; - } - else - { - val_print (VALUE_TYPE (val), VALUE_CONTENTS (val) + typelen * i, - VALUE_ADDRESS (val) + typelen * i, stream, format, 1, - 0, pretty); - things_printed++; - } - } - if (i < n) - { - fprintf_filtered (stream, "..."); - } -} - -/* 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. */ - -/* FIXME: All callers supply LEN of zero. Supplying a non-zero LEN is - pointless, this routine just then becomes a convoluted version of - target_read_memory_partial. Removing all the LEN stuff would simplify - this routine enormously. - - FIXME: Use target_read_string. */ - -int -val_print_string (addr, len, stream) - CORE_ADDR addr; - unsigned int len; - 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. */ - int bufsize; /* Size of current fetch buffer. */ - 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. */ - - /* 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 - 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)); - - /* 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 - 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); - - /* 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); - - /* 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 */ - - /* 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. */ - - if (len == 0 && bufptr > buffer && *(bufptr - 1) != '\0') - { - /* 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; - } - } - else if ((len != 0 && errcode != 0) || (len > bufptr - buffer)) - { - /* Getting an error when we have a requested length, or fetching less - than the number of characters actually requested, always make us - print ellipsis. */ - force_ellipsis = 1; - } - - QUIT; - - /* If we get an error before fetching anything, don't print a string. - But if we fetch something and then get an error, print the string - and then the error message. */ - if (errcode == 0 || bufptr > buffer) - { - if (addressprint) - { - fputs_filtered (" ", stream); - } - LA_PRINT_STRING (stream, buffer, bufptr - buffer, force_ellipsis); - } - - if (errcode != 0) - { - if (errcode == EIO) - { - fprintf_filtered (stream, "
"); - } - else - { - fprintf_filtered (stream, " ", safe_strerror (errcode)); - } - } - gdb_flush (stream); - do_cleanups (old_chain); - return (bufptr - buffer); -} - - -/* Validate an input or output radix setting, and make sure the user - knows what they really did here. Radix setting is confusing, e.g. - setting the input radix to "10" never changes it! */ - -/* ARGSUSED */ -static void -set_input_radix (args, from_tty, c) - char *args; - int from_tty; - struct cmd_list_element *c; -{ - set_input_radix_1 (from_tty, *(unsigned *)c->var); -} - -/* ARGSUSED */ -static void -set_input_radix_1 (from_tty, radix) - int from_tty; - unsigned radix; -{ - /* We don't currently disallow any input radix except 0 or 1, which don't - make any mathematical sense. In theory, we can deal with any input - radix greater than 1, even if we don't have unique digits for every - value from 0 to radix-1, but in practice we lose on large radix values. - We should either fix the lossage or restrict the radix range more. - (FIXME). */ - - if (radix < 2) - { - error ("Nonsense input radix ``decimal %u''; input radix unchanged.", - radix); - } - input_radix = radix; - if (from_tty) - { - printf_filtered ("Input radix now set to decimal %u, hex %x, octal %o.\n", - radix, radix, radix); - } -} - -/* ARGSUSED */ -static void -set_output_radix (args, from_tty, c) - char *args; - int from_tty; - struct cmd_list_element *c; -{ - set_output_radix_1 (from_tty, *(unsigned *)c->var); -} - -static void -set_output_radix_1 (from_tty, radix) - int from_tty; - unsigned radix; -{ - /* Validate the radix and disallow ones that we aren't prepared to - handle correctly, leaving the radix unchanged. */ - switch (radix) - { - case 16: - output_format = 'x'; /* hex */ - break; - case 10: - output_format = 0; /* decimal */ - break; - case 8: - output_format = 'o'; /* octal */ - break; - default: - error ("Unsupported output radix ``decimal %u''; output radix unchanged.", - radix); - } - output_radix = radix; - if (from_tty) - { - printf_filtered ("Output radix now set to decimal %u, hex %x, octal %o.\n", - radix, radix, radix); - } -} - -/* Set both the input and output radix at once. Try to set the output radix - first, since it has the most restrictive range. An radix that is valid as - an output radix is also valid as an input radix. - - It may be useful to have an unusual input radix. If the user wishes to - set an input radix that is not valid as an output radix, he needs to use - the 'set input-radix' command. */ - -static void -set_radix (arg, from_tty) - char *arg; - int from_tty; -{ - unsigned radix; - - radix = (arg == NULL) ? 10 : parse_and_eval_address (arg); - set_output_radix_1 (0, radix); - set_input_radix_1 (0, radix); - if (from_tty) - { - printf_filtered ("Input and output radices now set to decimal %u, hex %x, octal %o.\n", - radix, radix, radix); - } -} - -/* Show both the input and output radices. */ - -/*ARGSUSED*/ -static void -show_radix (arg, from_tty) - char *arg; - int from_tty; -{ - if (from_tty) - { - if (input_radix == output_radix) - { - printf_filtered ("Input and output radices set to decimal %u, hex %x, octal %o.\n", - input_radix, input_radix, input_radix); - } - else - { - printf_filtered ("Input radix set to decimal %u, hex %x, octal %o.\n", - input_radix, input_radix, input_radix); - printf_filtered ("Output radix set to decimal %u, hex %x, octal %o.\n", - output_radix, output_radix, output_radix); - } - } -} - - -/*ARGSUSED*/ -static void -set_print (arg, from_tty) - char *arg; - int from_tty; -{ - printf_unfiltered ( -"\"set print\" must be followed by the name of a print subcommand.\n"); - help_list (setprintlist, "set print ", -1, gdb_stdout); -} - -/*ARGSUSED*/ -static void -show_print (args, from_tty) - char *args; - int from_tty; -{ - cmd_show_list (showprintlist, from_tty, ""); -} - -void -_initialize_valprint () -{ - struct cmd_list_element *c; - - add_prefix_cmd ("print", no_class, set_print, - "Generic command for setting how things print.", - &setprintlist, "set print ", 0, &setlist); - add_alias_cmd ("p", "print", no_class, 1, &setlist); - /* prefer set print to set prompt */ - add_alias_cmd ("pr", "print", no_class, 1, &setlist); - - add_prefix_cmd ("print", no_class, show_print, - "Generic command for showing print settings.", - &showprintlist, "show print ", 0, &showlist); - add_alias_cmd ("p", "print", no_class, 1, &showlist); - add_alias_cmd ("pr", "print", no_class, 1, &showlist); - - add_show_from_set - (add_set_cmd ("elements", no_class, var_uinteger, (char *)&print_max, - "Set limit on string chars or array elements to print.\n\ -\"set print elements 0\" causes there to be no limit.", - &setprintlist), - &showprintlist); - - add_show_from_set - (add_set_cmd ("null-stop", no_class, var_boolean, - (char *)&stop_print_at_null, - "Set printing of char arrays to stop at first null char.", - &setprintlist), - &showprintlist); - - add_show_from_set - (add_set_cmd ("repeats", no_class, var_uinteger, - (char *)&repeat_count_threshold, - "Set threshold for repeated print elements.\n\ -\"set print repeats 0\" causes all elements to be individually printed.", - &setprintlist), - &showprintlist); - - add_show_from_set - (add_set_cmd ("pretty", class_support, var_boolean, - (char *)&prettyprint_structs, - "Set prettyprinting of structures.", - &setprintlist), - &showprintlist); - - add_show_from_set - (add_set_cmd ("union", class_support, var_boolean, (char *)&unionprint, - "Set printing of unions interior to structures.", - &setprintlist), - &showprintlist); - - add_show_from_set - (add_set_cmd ("array", class_support, var_boolean, - (char *)&prettyprint_arrays, - "Set prettyprinting of arrays.", - &setprintlist), - &showprintlist); - - add_show_from_set - (add_set_cmd ("address", class_support, var_boolean, (char *)&addressprint, - "Set printing of addresses.", - &setprintlist), - &showprintlist); - - c = add_set_cmd ("input-radix", class_support, var_uinteger, - (char *)&input_radix, - "Set default input radix for entering numbers.", - &setlist); - add_show_from_set (c, &showlist); - c->function.sfunc = set_input_radix; - - c = add_set_cmd ("output-radix", class_support, var_uinteger, - (char *)&output_radix, - "Set default output radix for printing of values.", - &setlist); - add_show_from_set (c, &showlist); - c->function.sfunc = set_output_radix; - - /* The "set radix" and "show radix" commands are special in that they are - like normal set and show commands but allow two normally independent - variables to be either set or shown with a single command. So the - usual add_set_cmd() and add_show_from_set() commands aren't really - appropriate. */ - add_cmd ("radix", class_support, set_radix, - "Set default input and output number radices.\n\ -Use 'set input-radix' or 'set output-radix' to independently set each.\n\ -Without an argument, sets both radices back to the default value of 10.", - &setlist); - add_cmd ("radix", class_support, show_radix, - "Show the default input and output number radices.\n\ -Use 'show input-radix' or 'show output-radix' to independently show each.", - &showlist); - - /* Give people the defaults which they are used to. */ - prettyprint_structs = 0; - prettyprint_arrays = 0; - unionprint = 1; - addressprint = 1; - print_max = PRINT_MAX_DEFAULT; -} diff --git a/gnu/usr.bin/gdb/gdb/valprint.h b/gnu/usr.bin/gdb/gdb/valprint.h deleted file mode 100644 index e45f48d..0000000 --- a/gnu/usr.bin/gdb/gdb/valprint.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Declarations for value printing routines for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 1992, 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. */ - - -extern int prettyprint_arrays; /* Controls pretty printing of arrays. */ -extern int prettyprint_structs; /* Controls pretty printing of structures */ -extern int prettyprint_arrays; /* Controls pretty printing of arrays. */ - -extern int vtblprint; /* Controls printing of vtbl's */ -extern int unionprint; /* Controls printing of nested unions. */ -extern int addressprint; /* Controls pretty printing of addresses. */ -extern int objectprint; /* Controls looking up an object's derived type - using what we find in its vtables. */ - -extern unsigned int print_max; /* Max # of chars for strings/vectors */ - -extern int output_format; - -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)); - -extern void -val_print_type_code_int PARAMS ((struct type *, char *, GDB_FILE *)); - diff --git a/gnu/usr.bin/gdb/gdb/value.h b/gnu/usr.bin/gdb/gdb/value.h deleted file mode 100644 index 31d3585..0000000 --- a/gnu/usr.bin/gdb/gdb/value.h +++ /dev/null @@ -1,482 +0,0 @@ -/* Definitions for values of C expressions, for GDB. - Copyright 1986, 1987, 1989, 1992, 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. */ - -#if !defined (VALUE_H) -#define VALUE_H 1 - -/* - * The structure which defines the type of a value. It should never - * be possible for a program lval value to survive over a call to the inferior - * (ie to be put into the history list or an internal variable). - */ -enum lval_type { - /* Not an lval. */ - not_lval, - /* In memory. Could be a saved register. */ - lval_memory, - /* In a register. */ - lval_register, - /* In a gdb internal variable. */ - lval_internalvar, - /* Part of a gdb internal variable (structure field). */ - lval_internalvar_component, - /* In a register series in a frame not the current one, which may have been - partially saved or saved in different places (otherwise would be - lval_register or lval_memory). */ - lval_reg_frame_relative -}; - -struct value - { - /* Type of value; either not an lval, or one of the various - different possible kinds of lval. */ - enum lval_type lval; - /* Is it modifiable? Only relevant if lval != not_lval. */ - int modifiable; - /* Location of value (if lval). */ - union - { - /* Address in inferior or byte of registers structure. */ - CORE_ADDR address; - /* Pointer to internal variable. */ - struct internalvar *internalvar; - /* Number of register. Only used with - lval_reg_frame_relative. */ - int regnum; - } location; - /* Describes offset of a value within lval a structure in bytes. */ - int offset; - /* Only used for bitfields; number of bits contained in them. */ - int bitsize; - /* Only used for bitfields; position of start of field. - For BITS_BIG_ENDIAN=0 targets, it is the position of the LSB. - For BITS_BIG_ENDIAN=1 targets, it is the position of the MSB. */ - int bitpos; - /* Frame value is relative to. In practice, this address is only - used if the value is stored in several registers in other than - the current frame, and these registers have not all been saved - at the same place in memory. This will be described in the - lval enum above as "lval_reg_frame_relative". */ - CORE_ADDR frame_addr; - /* Type of the value. */ - struct type *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 - list. */ - struct value *next; - /* If an lval is forced to repeat, a new value is created with - these fields set. The new value is not an lval. */ - short repeated; - short repetitions; - /* Register number if the value is from a register. Is not kept - if you take a field of a structure that is stored in a - register. Shouldn't it be? */ - short regno; - /* If zero, contents of this value are in the contents field. - If nonzero, contents are in inferior memory at address - in the location.address field plus the offset field - (and the lval field should be lval_memory). */ - char lazy; - /* If nonzero, this is the value of a variable which does not - actually exist in the program. */ - char optimized_out; - /* 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. */ - union { - long contents[1]; - double force_double_align; - LONGEST force_longlong_align; - } aligner; - - }; - -typedef struct value *value_ptr; - -#define VALUE_TYPE(val) (val)->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. - VALUE_CONTENTS is used when the contents of the buffer are needed -- - 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) -#define VALUE_CONTENTS(val) ((void)(VALUE_LAZY(val) && value_fetch_lazy(val)),\ - VALUE_CONTENTS_RAW(val)) -extern int value_fetch_lazy PARAMS ((value_ptr val)); - -#define VALUE_LVAL(val) (val)->lval -#define VALUE_ADDRESS(val) (val)->location.address -#define VALUE_INTERNALVAR(val) (val)->location.internalvar -#define VALUE_FRAME_REGNUM(val) ((val)->location.regnum) -#define VALUE_FRAME(val) ((val)->frame_addr) -#define VALUE_OFFSET(val) (val)->offset -#define VALUE_BITSIZE(val) (val)->bitsize -#define VALUE_BITPOS(val) (val)->bitpos -#define VALUE_NEXT(val) (val)->next -#define VALUE_REPEATED(val) (val)->repeated -#define VALUE_REPETITIONS(val) (val)->repetitions -#define VALUE_REGNO(val) (val)->regno -#define VALUE_OPTIMIZED_OUT(val) ((val)->optimized_out) - -/* 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)));} - -/* If ARG is an array, convert it to a pointer. - If ARG is an enum, convert it to an integer. - If ARG is a function, convert it to a function pointer. - - References are dereferenced. */ - -#define COERCE_ARRAY(arg) \ -{ COERCE_REF(arg); \ - if (VALUE_REPEATED (arg) \ - || TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY) \ - arg = value_coerce_array (arg); \ - if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FUNC) \ - arg = value_coerce_function (arg); \ - if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ENUM) \ - arg = value_cast (builtin_type_unsigned_int, arg); \ -} - -/* If ARG is an enum, convert it to an integer. */ - -#define COERCE_ENUM(arg) \ -{ COERCE_REF (arg); \ - if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ENUM) \ - arg = value_cast (builtin_type_unsigned_int, arg); \ -} - -/* Internal variables (variables for convenience of use of debugger) - are recorded as a chain of these structures. */ - -struct internalvar -{ - struct internalvar *next; - char *name; - value_ptr value; -}; - -/* Pointer to member function. Depends on compiler implementation. */ - -#define METHOD_PTR_IS_VIRTUAL(ADDR) ((ADDR) & 0x80000000) -#define METHOD_PTR_FROM_VOFFSET(OFFSET) (0x80000000 + (OFFSET)) -#define METHOD_PTR_TO_VOFFSET(ADDR) (~0x80000000 & (ADDR)) - - -#include "symtab.h" -#include "gdbtypes.h" -#include "expression.h" - -#ifdef __STDC__ -struct frame_info; -struct fn_field; -#endif - -extern void -print_address_demangle PARAMS ((CORE_ADDR, GDB_FILE *, int)); - -extern LONGEST value_as_long PARAMS ((value_ptr val)); - -extern double value_as_double PARAMS ((value_ptr val)); - -extern CORE_ADDR value_as_pointer PARAMS ((value_ptr val)); - -extern LONGEST unpack_long PARAMS ((struct type *type, char *valaddr)); - -extern double unpack_double PARAMS ((struct type *type, char *valaddr, - int *invp)); - -extern CORE_ADDR unpack_pointer PARAMS ((struct type *type, char *valaddr)); - -extern LONGEST unpack_field_as_long PARAMS ((struct type *type, char *valaddr, - int fieldno)); - -extern value_ptr value_from_longest PARAMS ((struct type *type, LONGEST num)); - -extern value_ptr value_from_double PARAMS ((struct type *type, double num)); - -extern value_ptr value_at PARAMS ((struct type *type, CORE_ADDR addr)); - -extern value_ptr value_at_lazy PARAMS ((struct type *type, CORE_ADDR addr)); - -/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */ -extern value_ptr value_from_register PARAMS ((struct type *type, int regnum, - struct frame_info * frame)); - -extern value_ptr value_of_variable PARAMS ((struct symbol *var, - struct block *b)); - -extern value_ptr value_of_register PARAMS ((int regnum)); - -extern int symbol_read_needs_frame PARAMS ((struct symbol *)); - -/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */ -extern value_ptr read_var_value PARAMS ((struct symbol *var, - struct frame_info *frame)); - -/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */ -extern value_ptr locate_var_value PARAMS ((struct symbol *var, - struct frame_info *frame)); - -extern value_ptr allocate_value PARAMS ((struct type *type)); - -extern value_ptr allocate_repeat_value PARAMS ((struct type *type, int count)); - -extern value_ptr value_mark PARAMS ((void)); - -extern void value_free_to_mark PARAMS ((value_ptr mark)); - -extern value_ptr value_string PARAMS ((char *ptr, int len)); - -extern value_ptr value_array PARAMS ((int lowbound, int highbound, - value_ptr *elemvec)); - -extern value_ptr value_concat PARAMS ((value_ptr arg1, value_ptr arg2)); - -extern value_ptr value_binop PARAMS ((value_ptr arg1, value_ptr arg2, - enum exp_opcode op)); - -extern value_ptr value_add PARAMS ((value_ptr arg1, value_ptr arg2)); - -extern value_ptr value_sub PARAMS ((value_ptr arg1, value_ptr arg2)); - -extern value_ptr value_coerce_array PARAMS ((value_ptr arg1)); - -extern value_ptr value_coerce_function PARAMS ((value_ptr arg1)); - -extern value_ptr value_ind PARAMS ((value_ptr arg1)); - -extern value_ptr value_addr PARAMS ((value_ptr arg1)); - -extern value_ptr value_assign PARAMS ((value_ptr toval, value_ptr fromval)); - -extern value_ptr value_neg PARAMS ((value_ptr arg1)); - -extern value_ptr value_complement PARAMS ((value_ptr arg1)); - -extern value_ptr value_struct_elt PARAMS ((value_ptr *argp, value_ptr *args, - char *name, - int *static_memfuncp, char *err)); - -extern value_ptr value_struct_elt_for_reference PARAMS ((struct type *domain, - int offset, - struct type *curtype, - char *name, - struct type *intype)); - -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 value_ptr value_cast PARAMS ((struct type *type, value_ptr arg2)); - -extern value_ptr value_zero PARAMS ((struct type *type, enum lval_type lv)); - -extern value_ptr value_repeat PARAMS ((value_ptr arg1, int count)); - -extern value_ptr value_subscript PARAMS ((value_ptr array, value_ptr idx)); - -extern value_ptr value_from_vtable_info PARAMS ((value_ptr arg, - struct type *type)); - -extern value_ptr value_being_returned PARAMS ((struct type *valtype, - char retbuf[REGISTER_BYTES], - int struct_return)); - -extern value_ptr value_in PARAMS ((value_ptr element, value_ptr set)); - -extern int value_bit_index PARAMS ((struct type *type, char *addr, int index)); - -extern int using_struct_return PARAMS ((value_ptr function, CORE_ADDR funcaddr, - struct type *value_type, int gcc_p)); - -extern void set_return_value PARAMS ((value_ptr val)); - -extern value_ptr evaluate_expression PARAMS ((struct expression *exp)); - -extern value_ptr evaluate_type PARAMS ((struct expression *exp)); - -extern value_ptr parse_and_eval PARAMS ((char *exp)); - -extern value_ptr parse_to_comma_and_eval PARAMS ((char **expp)); - -extern struct type *parse_and_eval_type PARAMS ((char *p, int length)); - -extern CORE_ADDR parse_and_eval_address PARAMS ((char *exp)); - -extern CORE_ADDR parse_and_eval_address_1 PARAMS ((char **expptr)); - -extern value_ptr access_value_history PARAMS ((int num)); - -extern value_ptr value_of_internalvar PARAMS ((struct internalvar *var)); - -extern void set_internalvar PARAMS ((struct internalvar *var, value_ptr val)); - -extern void set_internalvar_component PARAMS ((struct internalvar *var, - int offset, - int bitpos, int bitsize, - value_ptr newvalue)); - -extern struct internalvar *lookup_internalvar PARAMS ((char *name)); - -extern int value_equal PARAMS ((value_ptr arg1, value_ptr arg2)); - -extern int value_less PARAMS ((value_ptr arg1, value_ptr arg2)); - -extern int value_logical_not PARAMS ((value_ptr arg1)); - -/* C++ */ - -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)); - -extern value_ptr value_x_unop PARAMS ((value_ptr arg1, enum exp_opcode op)); - -extern value_ptr value_fn_field PARAMS ((value_ptr *arg1p, struct fn_field *f, - int j, - struct type* type, int offset)); - -extern value_ptr value_virtual_fn_field PARAMS ((value_ptr *arg1p, - struct fn_field *f, int j, - struct type *type, - int offset)); - -extern int binop_user_defined_p PARAMS ((enum exp_opcode op, - value_ptr arg1, value_ptr arg2)); - -extern int unop_user_defined_p PARAMS ((enum exp_opcode op, value_ptr arg1)); - -extern int destructor_name_p PARAMS ((const char *name, - const struct type *type)); - -#define value_free(val) free ((PTR)val) - -extern void free_all_values PARAMS ((void)); - -extern void release_value PARAMS ((value_ptr val)); - -extern int record_latest_value PARAMS ((value_ptr val)); - -extern void registers_changed PARAMS ((void)); - -extern void read_register_bytes PARAMS ((int regbyte, char *myaddr, int len)); - -extern void write_register_bytes PARAMS ((int regbyte, char *myaddr, int len)); - -extern void -read_register_gen PARAMS ((int regno, char *myaddr)); - -extern CORE_ADDR -read_register PARAMS ((int regno)); - -extern void -write_register PARAMS ((int regno, LONGEST val)); - -extern void -supply_register PARAMS ((int regno, char *val)); - -/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */ -extern void -get_saved_register PARAMS ((char *raw_buffer, int *optimized, - CORE_ADDR *addrp, struct frame_info *frame, - int regnum, enum lval_type *lval)); - -extern void -modify_field PARAMS ((char *addr, LONGEST fieldval, int bitpos, int bitsize)); - -extern void -type_print PARAMS ((struct type *type, char *varstring, GDB_FILE *stream, - int show)); - -extern char *baseclass_addr PARAMS ((struct type *type, int index, - char *valaddr, - value_ptr *valuep, int *errp)); - -extern void -print_longest PARAMS ((GDB_FILE *stream, int format, int use_local, - LONGEST val)); - -extern void -print_floating PARAMS ((char *valaddr, struct type *type, GDB_FILE *stream)); - -extern int value_print PARAMS ((value_ptr val, GDB_FILE *stream, int format, - enum val_prettyprint pretty)); - -extern void -value_print_array_elements PARAMS ((value_ptr val, GDB_FILE* stream, - int format, enum val_prettyprint pretty)); - -extern value_ptr -value_release_to_mark PARAMS ((value_ptr mark)); - -extern int -val_print PARAMS ((struct type *type, char *valaddr, 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)); - -/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */ -extern void -print_variable_value PARAMS ((struct symbol *var, struct frame_info *frame, - GDB_FILE *stream)); - -extern value_ptr value_arg_coerce PARAMS ((value_ptr)); - -extern int check_field PARAMS ((value_ptr, const char *)); - -extern void -c_typedef_print PARAMS ((struct type *type, struct symbol *new, GDB_FILE *stream)); - -extern char * -internalvar_name PARAMS ((struct internalvar *var)); - -extern void -clear_value_history PARAMS ((void)); - -extern void -clear_internalvars PARAMS ((void)); - -/* From values.c */ - -extern value_ptr value_copy PARAMS ((value_ptr)); - -extern int baseclass_offset PARAMS ((struct type *, int, value_ptr, int)); - -/* From valops.c */ - -extern value_ptr call_function_by_hand PARAMS ((value_ptr, int, value_ptr *)); - -#endif /* !defined (VALUE_H) */ diff --git a/gnu/usr.bin/gdb/gdb/values.c b/gnu/usr.bin/gdb/gdb/values.c deleted file mode 100644 index 3a2dd43..0000000 --- a/gnu/usr.bin/gdb/gdb/values.c +++ /dev/null @@ -1,1508 +0,0 @@ -/* Low level packing and unpacking of values for GDB, the GNU Debugger. - Copyright 1986, 1987, 1989, 1991 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 "defs.h" -#include -#include "symtab.h" -#include "gdbtypes.h" -#include "value.h" -#include "gdbcore.h" -#include "frame.h" -#include "command.h" -#include "gdbcmd.h" -#include "target.h" -#include "demangle.h" - -/* Local function prototypes. */ - -static value_ptr value_headof PARAMS ((value_ptr, struct type *, - struct type *)); - -static void show_values PARAMS ((char *, int)); - -static void show_convenience PARAMS ((char *, int)); - -/* The value-history records all the values printed - by print commands during this session. Each chunk - records 60 consecutive values. The first chunk on - the chain records the most recent values. - The total number of values is in value_history_count. */ - -#define VALUE_HISTORY_CHUNK 60 - -struct value_history_chunk -{ - struct value_history_chunk *next; - value_ptr values[VALUE_HISTORY_CHUNK]; -}; - -/* Chain of chunks now in use. */ - -static struct value_history_chunk *value_history_chain; - -static int value_history_count; /* Abs number of last entry stored */ - -/* List of all value objects currently allocated - (except for those released by calls to release_value) - This is so they can be freed after each command. */ - -static value_ptr all_values; - -/* Allocate a value that has the correct length for type TYPE. */ - -value_ptr -allocate_value (type) - struct type *type; -{ - register value_ptr val; - - check_stub_type (type); - - val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (type)); - VALUE_NEXT (val) = all_values; - all_values = val; - VALUE_TYPE (val) = type; - VALUE_LVAL (val) = not_lval; - VALUE_ADDRESS (val) = 0; - VALUE_FRAME (val) = 0; - VALUE_OFFSET (val) = 0; - VALUE_BITPOS (val) = 0; - VALUE_BITSIZE (val) = 0; - VALUE_REPEATED (val) = 0; - VALUE_REPETITIONS (val) = 0; - VALUE_REGNO (val) = -1; - VALUE_LAZY (val) = 0; - VALUE_OPTIMIZED_OUT (val) = 0; - val->modifiable = 1; - return val; -} - -/* Allocate a value that has the correct length - for COUNT repetitions type TYPE. */ - -value_ptr -allocate_repeat_value (type, count) - struct type *type; - int count; -{ - register value_ptr val; - - val = - (value_ptr) xmalloc (sizeof (struct value) + TYPE_LENGTH (type) * count); - VALUE_NEXT (val) = all_values; - all_values = val; - VALUE_TYPE (val) = type; - VALUE_LVAL (val) = not_lval; - VALUE_ADDRESS (val) = 0; - VALUE_FRAME (val) = 0; - VALUE_OFFSET (val) = 0; - VALUE_BITPOS (val) = 0; - VALUE_BITSIZE (val) = 0; - VALUE_REPEATED (val) = 1; - VALUE_REPETITIONS (val) = count; - VALUE_REGNO (val) = -1; - VALUE_LAZY (val) = 0; - VALUE_OPTIMIZED_OUT (val) = 0; - return val; -} - -/* Return a mark in the value chain. All values allocated after the - mark is obtained (except for those released) are subject to being freed - if a subsequent value_free_to_mark is passed the mark. */ -value_ptr -value_mark () -{ - return all_values; -} - -/* Free all values allocated since MARK was obtained by value_mark - (except for those released). */ -void -value_free_to_mark (mark) - value_ptr mark; -{ - value_ptr val, next; - - for (val = all_values; val && val != mark; val = next) - { - next = VALUE_NEXT (val); - value_free (val); - } - all_values = val; -} - -/* Free all the values that have been allocated (except for those released). - Called after each command, successful or not. */ - -void -free_all_values () -{ - register value_ptr val, next; - - for (val = all_values; val; val = next) - { - next = VALUE_NEXT (val); - value_free (val); - } - - all_values = 0; -} - -/* Remove VAL from the chain all_values - so it will not be freed automatically. */ - -void -release_value (val) - register value_ptr val; -{ - register value_ptr v; - - if (all_values == val) - { - all_values = val->next; - return; - } - - for (v = all_values; v; v = v->next) - { - if (v->next == val) - { - v->next = val->next; - break; - } - } -} - -/* Release all values up to mark */ -value_ptr -value_release_to_mark (mark) - value_ptr mark; -{ - value_ptr val, next; - - for (val = next = all_values; next; next = VALUE_NEXT (next)) - if (VALUE_NEXT (next) == mark) - { - all_values = VALUE_NEXT (next); - VALUE_NEXT (next) = 0; - return val; - } - all_values = 0; - return val; -} - -/* Return a copy of the value ARG. - It contains the same contents, for same memory address, - but it's a different block of storage. */ - -value_ptr -value_copy (arg) - value_ptr arg; -{ - register value_ptr val; - register struct type *type = VALUE_TYPE (arg); - if (VALUE_REPEATED (arg)) - val = allocate_repeat_value (type, VALUE_REPETITIONS (arg)); - else - val = allocate_value (type); - VALUE_LVAL (val) = VALUE_LVAL (arg); - VALUE_ADDRESS (val) = VALUE_ADDRESS (arg); - VALUE_OFFSET (val) = VALUE_OFFSET (arg); - VALUE_BITPOS (val) = VALUE_BITPOS (arg); - VALUE_BITSIZE (val) = VALUE_BITSIZE (arg); - VALUE_REGNO (val) = VALUE_REGNO (arg); - VALUE_LAZY (val) = VALUE_LAZY (arg); - val->modifiable = arg->modifiable; - if (!VALUE_LAZY (val)) - { - memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS_RAW (arg), - TYPE_LENGTH (VALUE_TYPE (arg)) - * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1)); - } - return val; -} - -/* Access to the value history. */ - -/* Record a new value in the value history. - Returns the absolute history index of the entry. - Result of -1 indicates the value was not saved; otherwise it is the - value history index of this new item. */ - -int -record_latest_value (val) - value_ptr val; -{ - int i; - - /* Check error now if about to store an invalid float. We return -1 - to the caller, but allow them to continue, e.g. to print it as "Nan". */ - if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT) - { - unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &i); - if (i) return -1; /* Indicate value not saved in history */ - } - - /* Here we treat value_history_count as origin-zero - and applying to the value being stored now. */ - - i = value_history_count % VALUE_HISTORY_CHUNK; - if (i == 0) - { - register struct value_history_chunk *new - = (struct value_history_chunk *) - xmalloc (sizeof (struct value_history_chunk)); - memset (new->values, 0, sizeof new->values); - new->next = value_history_chain; - value_history_chain = new; - } - - value_history_chain->values[i] = val; - - /* We don't want this value to have anything to do with the inferior anymore. - In particular, "set $1 = 50" should not affect the variable from which - the value was taken, and fast watchpoints should be able to assume that - a value on the value history never changes. */ - if (VALUE_LAZY (val)) - value_fetch_lazy (val); - /* We preserve VALUE_LVAL so that the user can find out where it was fetched - from. This is a bit dubious, because then *&$1 does not just return $1 - but the current contents of that location. c'est la vie... */ - val->modifiable = 0; - release_value (val); - - /* Now we regard value_history_count as origin-one - and applying to the value just stored. */ - - return ++value_history_count; -} - -/* Return a copy of the value in the history with sequence number NUM. */ - -value_ptr -access_value_history (num) - int num; -{ - register struct value_history_chunk *chunk; - register int i; - register int absnum = num; - - if (absnum <= 0) - absnum += value_history_count; - - if (absnum <= 0) - { - if (num == 0) - error ("The history is empty."); - else if (num == 1) - error ("There is only one value in the history."); - else - error ("History does not go back to $$%d.", -num); - } - if (absnum > value_history_count) - error ("History has not yet reached $%d.", absnum); - - absnum--; - - /* Now absnum is always absolute and origin zero. */ - - chunk = value_history_chain; - for (i = (value_history_count - 1) / VALUE_HISTORY_CHUNK - absnum / VALUE_HISTORY_CHUNK; - i > 0; i--) - chunk = chunk->next; - - return value_copy (chunk->values[absnum % VALUE_HISTORY_CHUNK]); -} - -/* Clear the value history entirely. - Must be done when new symbol tables are loaded, - because the type pointers become invalid. */ - -void -clear_value_history () -{ - register struct value_history_chunk *next; - register int i; - register value_ptr val; - - while (value_history_chain) - { - for (i = 0; i < VALUE_HISTORY_CHUNK; i++) - if ((val = value_history_chain->values[i]) != NULL) - free ((PTR)val); - next = value_history_chain->next; - free ((PTR)value_history_chain); - value_history_chain = next; - } - value_history_count = 0; -} - -static void -show_values (num_exp, from_tty) - char *num_exp; - int from_tty; -{ - register int i; - register value_ptr val; - static int num = 1; - - if (num_exp) - { - /* "info history +" should print from the stored position. - "info history " should print around value number . */ - if (num_exp[0] != '+' || num_exp[1] != '\0') - num = parse_and_eval_address (num_exp) - 5; - } - else - { - /* "info history" means print the last 10 values. */ - num = value_history_count - 9; - } - - if (num <= 0) - num = 1; - - for (i = num; i < num + 10 && i <= value_history_count; i++) - { - val = access_value_history (i); - printf_filtered ("$%d = ", i); - value_print (val, gdb_stdout, 0, Val_pretty_default); - printf_filtered ("\n"); - } - - /* The next "info history +" should start after what we just printed. */ - num += 10; - - /* Hitting just return after this command should do the same thing as - "info history +". If num_exp is null, this is unnecessary, since - "info history +" is not useful after "info history". */ - if (from_tty && num_exp) - { - num_exp[0] = '+'; - num_exp[1] = '\0'; - } -} - -/* Internal variables. These are variables within the debugger - that hold values assigned by debugger commands. - The user refers to them with a '$' prefix - that does not appear in the variable names stored internally. */ - -static struct internalvar *internalvars; - -/* Look up an internal variable with name NAME. NAME should not - normally include a dollar sign. - - If the specified internal variable does not exist, - one is created, with a void value. */ - -struct internalvar * -lookup_internalvar (name) - char *name; -{ - register struct internalvar *var; - - for (var = internalvars; var; var = var->next) - if (STREQ (var->name, name)) - return var; - - var = (struct internalvar *) xmalloc (sizeof (struct internalvar)); - var->name = concat (name, NULL); - var->value = allocate_value (builtin_type_void); - release_value (var->value); - var->next = internalvars; - internalvars = var; - return var; -} - -value_ptr -value_of_internalvar (var) - struct internalvar *var; -{ - register value_ptr val; - -#ifdef IS_TRAPPED_INTERNALVAR - if (IS_TRAPPED_INTERNALVAR (var->name)) - return VALUE_OF_TRAPPED_INTERNALVAR (var); -#endif - - val = value_copy (var->value); - if (VALUE_LAZY (val)) - value_fetch_lazy (val); - VALUE_LVAL (val) = lval_internalvar; - VALUE_INTERNALVAR (val) = var; - return val; -} - -void -set_internalvar_component (var, offset, bitpos, bitsize, newval) - struct internalvar *var; - int offset, bitpos, bitsize; - value_ptr newval; -{ - register char *addr = VALUE_CONTENTS (var->value) + offset; - -#ifdef IS_TRAPPED_INTERNALVAR - if (IS_TRAPPED_INTERNALVAR (var->name)) - SET_TRAPPED_INTERNALVAR (var, newval, bitpos, bitsize, offset); -#endif - - if (bitsize) - modify_field (addr, value_as_long (newval), - bitpos, bitsize); - else - memcpy (addr, VALUE_CONTENTS (newval), TYPE_LENGTH (VALUE_TYPE (newval))); -} - -void -set_internalvar (var, val) - struct internalvar *var; - value_ptr val; -{ - value_ptr newval; - -#ifdef IS_TRAPPED_INTERNALVAR - if (IS_TRAPPED_INTERNALVAR (var->name)) - SET_TRAPPED_INTERNALVAR (var, val, 0, 0, 0); -#endif - - newval = value_copy (val); - - /* Force the value to be fetched from the target now, to avoid problems - later when this internalvar is referenced and the target is gone or - has changed. */ - if (VALUE_LAZY (newval)) - value_fetch_lazy (newval); - - /* Begin code which must not call error(). If var->value points to - something free'd, an error() obviously leaves a dangling pointer. - But we also get a danling pointer if var->value points to - something in the value chain (i.e., before release_value is - called), because after the error free_all_values will get called before - long. */ - free ((PTR)var->value); - var->value = newval; - release_value (newval); - /* End code which must not call error(). */ -} - -char * -internalvar_name (var) - struct internalvar *var; -{ - return var->name; -} - -/* Free all internalvars. Done when new symtabs are loaded, - because that makes the values invalid. */ - -void -clear_internalvars () -{ - register struct internalvar *var; - - while (internalvars) - { - var = internalvars; - internalvars = var->next; - free ((PTR)var->name); - free ((PTR)var->value); - free ((PTR)var); - } -} - -static void -show_convenience (ignore, from_tty) - char *ignore; - int from_tty; -{ - register struct internalvar *var; - int varseen = 0; - - for (var = internalvars; var; var = var->next) - { -#ifdef IS_TRAPPED_INTERNALVAR - if (IS_TRAPPED_INTERNALVAR (var->name)) - continue; -#endif - if (!varseen) - { - varseen = 1; - } - printf_filtered ("$%s = ", var->name); - value_print (var->value, gdb_stdout, 0, Val_pretty_default); - printf_filtered ("\n"); - } - if (!varseen) - printf_unfiltered ("No debugger convenience variables now defined.\n\ -Convenience variables have names starting with \"$\";\n\ -use \"set\" as in \"set $foo = 5\" to define them.\n"); -} - -/* Extract a value as a C number (either long or double). - Knows how to convert fixed values to double, or - floating values to long. - Does not deallocate the value. */ - -LONGEST -value_as_long (val) - register value_ptr val; -{ - /* This coerces arrays and functions, which is necessary (e.g. - in disassemble_command). It also dereferences references, which - I suspect is the most logical thing to do. */ - if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_ENUM) - COERCE_ARRAY (val); - return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val)); -} - -double -value_as_double (val) - register value_ptr val; -{ - double foo; - int inv; - - foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv); - if (inv) - error ("Invalid floating value found in program."); - return foo; -} -/* Extract a value as a C pointer. - Does not deallocate the value. */ -CORE_ADDR -value_as_pointer (val) - value_ptr val; -{ - /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure - whether we want this to be true eventually. */ -#if 0 - /* ADDR_BITS_REMOVE is wrong if we are being called for a - non-address (e.g. argument to "signal", "info break", etc.), or - for pointers to char, in which the low bits *are* significant. */ - return ADDR_BITS_REMOVE(value_as_long (val)); -#else - return value_as_long (val); -#endif -} - -/* Unpack raw data (copied from debugee, target byte order) at VALADDR - as a long, or as a double, assuming the raw data is described - by type TYPE. Knows how to convert different sizes of values - and can convert between fixed and floating point. We don't assume - any alignment for the raw data. Return value is in host byte order. - - If you want functions and arrays to be coerced to pointers, and - references to be dereferenced, call value_as_long() instead. - - C++: It is assumed that the front-end has taken care of - all matters concerning pointers to members. A pointer - to member which reaches here is considered to be equivalent - to an INT (or some size). After all, it is only an offset. */ - -LONGEST -unpack_long (type, valaddr) - struct type *type; - char *valaddr; -{ - register enum type_code code = TYPE_CODE (type); - register int len = TYPE_LENGTH (type); - register int nosign = TYPE_UNSIGNED (type); - - switch (code) - { - case TYPE_CODE_ENUM: - case TYPE_CODE_BOOL: - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_RANGE: - if (nosign) - return extract_unsigned_integer (valaddr, len); - else - return extract_signed_integer (valaddr, len); - - case TYPE_CODE_FLT: - return extract_floating (valaddr, len); - - case TYPE_CODE_PTR: - 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. */ - return extract_address (valaddr, len); - - case TYPE_CODE_MEMBER: - error ("not implemented: member types in unpack_long"); - - default: - error ("Value can't be converted to integer."); - } - return 0; /* Placate lint. */ -} - -/* Return a double value from the specified type and address. - INVP points to an int which is set to 0 for valid value, - 1 for invalid value (bad float format). In either case, - the returned double is OK to use. Argument is in target - format, result is in host format. */ - -double -unpack_double (type, valaddr, invp) - struct type *type; - char *valaddr; - int *invp; -{ - register enum type_code code = TYPE_CODE (type); - register int len = TYPE_LENGTH (type); - register int nosign = TYPE_UNSIGNED (type); - - *invp = 0; /* Assume valid. */ - if (code == TYPE_CODE_FLT) - { - if (INVALID_FLOAT (valaddr, len)) - { - *invp = 1; - return 1.234567891011121314; - } - return extract_floating (valaddr, len); - } - else if (nosign) - { - /* Unsigned -- be sure we compensate for signed LONGEST. */ - return (unsigned LONGEST) unpack_long (type, valaddr); - } - else - { - /* Signed -- we are OK with unpack_long. */ - return unpack_long (type, valaddr); - } -} - -/* Unpack raw data (copied from debugee, target byte order) at VALADDR - as a CORE_ADDR, assuming the raw data is described by type TYPE. - We don't assume any alignment for the raw data. Return value is in - host byte order. - - If you want functions and arrays to be coerced to pointers, and - references to be dereferenced, call value_as_pointer() instead. - - C++: It is assumed that the front-end has taken care of - all matters concerning pointers to members. A pointer - to member which reaches here is considered to be equivalent - to an INT (or some size). After all, it is only an offset. */ - -CORE_ADDR -unpack_pointer (type, valaddr) - struct type *type; - char *valaddr; -{ - /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure - whether we want this to be true eventually. */ - return unpack_long (type, valaddr); -} - -/* 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 */ - -value_ptr -value_primitive_field (arg1, offset, fieldno, arg_type) - register value_ptr arg1; - int offset; - register int fieldno; - register struct type *arg_type; -{ - register value_ptr v; - register struct type *type; - - check_stub_type (arg_type); - type = TYPE_FIELD_TYPE (arg_type, fieldno); - - /* 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)); - VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8; - VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno); - } - else - { - v = allocate_value (type); - if (VALUE_LAZY (arg1)) - VALUE_LAZY (v) = 1; - else - memcpy (VALUE_CONTENTS_RAW (v), VALUE_CONTENTS_RAW (arg1) + offset, - TYPE_LENGTH (type)); - } - 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); - 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 */ - -value_ptr -value_field (arg1, fieldno) - register value_ptr arg1; - register int fieldno; -{ - return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1)); -} - -/* Return a non-virtual function as a value. - F is the list of member functions which contains the desired method. - J is an index into F which provides the desired method. */ - -value_ptr -value_fn_field (arg1p, f, j, type, offset) - value_ptr *arg1p; - struct fn_field *f; - int j; - struct type *type; - int offset; -{ - register value_ptr v; - register struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); - struct symbol *sym; - - sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j), - 0, VAR_NAMESPACE, 0, NULL); - if (! sym) - return NULL; -/* - error ("Internal error: could not find physical method named %s", - TYPE_FN_FIELD_PHYSNAME (f, j)); -*/ - - v = allocate_value (ftype); - VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); - VALUE_TYPE (v) = ftype; - - if (arg1p) - { - if (type != VALUE_TYPE (*arg1p)) - *arg1p = value_ind (value_cast (lookup_pointer_type (type), - value_addr (*arg1p))); - - /* Move the `this' pointer according to the offset. - VALUE_OFFSET (*arg1p) += offset; - */ - } - - return v; -} - -/* Return a virtual function as a value. - ARG1 is the object which provides the virtual function - table pointer. *ARG1P is side-effected in calling this function. - F is the list of member functions which contains the desired virtual - function. - J is an index into F which provides the desired virtual function. - - TYPE is the type in which F is located. */ -value_ptr -value_virtual_fn_field (arg1p, f, j, type, offset) - value_ptr *arg1p; - struct fn_field *f; - int j; - struct type *type; - int offset; -{ - value_ptr arg1 = *arg1p; - /* 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) != VALUE_TYPE (arg1)) - arg1 = value_ind (value_cast (context, value_addr (arg1))); - - context = VALUE_TYPE (arg1); - /* 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); - - if (TYPE_CODE (VALUE_TYPE (entry)) == TYPE_CODE_STRUCT) - { - /* Move the `this' pointer according to the virtual function table. */ - VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0)); - - if (! VALUE_LAZY (arg1)) - { - VALUE_LAZY (arg1) = 1; - value_fetch_lazy (arg1); - } - - vfn = value_field (entry, 2); - } - else if (TYPE_CODE (VALUE_TYPE (entry)) == 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 - a DTYPE. BTYPE is the most derived basetype that has - already been searched (and need not be searched again). - After looking at the vtables between BTYPE and DTYPE, - return the most derived type we find. The caller must - be satisfied when the return value == DTYPE. - - FIXME-tiemann: should work with dossier entries as well. */ - -static value_ptr -value_headof (in_arg, btype, dtype) - value_ptr in_arg; - struct type *btype, *dtype; -{ - /* First collect the vtables we must look at for this object. */ - /* FIXME-tiemann: right now, just look at top-most vtable. */ - value_ptr arg, vtbl, entry, best_entry = 0; - int i, nelems; - int offset, best_offset = 0; - struct symbol *sym; - CORE_ADDR pc_for_sym; - char *demangled_name; - struct minimal_symbol *msymbol; - - btype = TYPE_VPTR_BASETYPE (dtype); - check_stub_type (btype); - arg = in_arg; - if (btype != dtype) - arg = value_cast (lookup_pointer_type (btype), arg); - vtbl = value_ind (value_field (value_ind (arg), TYPE_VPTR_FIELDNO (btype))); - - /* Check that VTBL looks like it points to a virtual function table. */ - msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtbl)); - if (msymbol == NULL - || (demangled_name = SYMBOL_NAME (msymbol)) == NULL - || !VTBL_PREFIX_P (demangled_name)) - { - /* If we expected to find a vtable, but did not, let the user - know that we aren't happy, but don't throw an error. - FIXME: there has to be a better way to do this. */ - struct type *error_type = (struct type *)xmalloc (sizeof (struct type)); - memcpy (error_type, VALUE_TYPE (in_arg), sizeof (struct type)); - TYPE_NAME (error_type) = savestring ("suspicious *", sizeof ("suspicious *")); - VALUE_TYPE (in_arg) = error_type; - return in_arg; - } - - /* Now search through the virtual function table. */ - entry = value_ind (vtbl); - nelems = longest_to_int (value_as_long (value_field (entry, 2))); - for (i = 1; i <= nelems; i++) - { - entry = value_subscript (vtbl, value_from_longest (builtin_type_int, - (LONGEST) i)); - /* This won't work if we're using thunks. */ - if (TYPE_CODE (VALUE_TYPE (entry)) != TYPE_CODE_STRUCT) - break; - offset = longest_to_int (value_as_long (value_field (entry, 0))); - /* If we use '<=' we can handle single inheritance - * where all offsets are zero - just use the first entry found. */ - if (offset <= best_offset) - { - best_offset = offset; - best_entry = entry; - } - } - /* Move the pointer according to BEST_ENTRY's offset, and figure - out what type we should return as the new pointer. */ - if (best_entry == 0) - { - /* An alternative method (which should no longer be necessary). - * But we leave it in for future use, when we will hopefully - * have optimizes the vtable to use thunks instead of offsets. */ - /* Use the name of vtable itself to extract a base type. */ - demangled_name += 4; /* Skip _vt$ prefix. */ - } - else - { - pc_for_sym = value_as_pointer (value_field (best_entry, 2)); - sym = find_pc_function (pc_for_sym); - demangled_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ANSI); - *(strchr (demangled_name, ':')) = '\0'; - } - sym = lookup_symbol (demangled_name, 0, VAR_NAMESPACE, 0, 0); - if (sym == NULL) - error ("could not find type declaration for `%s'", demangled_name); - if (best_entry) - { - free (demangled_name); - arg = value_add (value_cast (builtin_type_int, arg), - value_field (best_entry, 0)); - } - else arg = in_arg; - VALUE_TYPE (arg) = lookup_pointer_type (SYMBOL_TYPE (sym)); - return arg; -} - -/* ARG is a pointer object of type TYPE. If TYPE has virtual - function tables, probe ARG's tables (including the vtables - of its baseclasses) to figure out the most derived type that ARG - could actually be a pointer to. */ - -value_ptr -value_from_vtable_info (arg, type) - value_ptr arg; - struct type *type; -{ - /* Take care of preliminaries. */ - if (TYPE_VPTR_FIELDNO (type) < 0) - fill_in_vptr_fieldno (type); - if (TYPE_VPTR_FIELDNO (type) < 0 || VALUE_REPEATED (arg)) - return 0; - - return value_headof (arg, 0, type); -} - -/* Return true if the INDEXth field of TYPE is a virtual baseclass - pointer which is for the base class whose type is BASECLASS. */ - -static int -vb_match (type, index, basetype) - struct type *type; - int index; - struct type *basetype; -{ - struct type *fieldtype; - char *name = TYPE_FIELD_NAME (type, index); - char *field_class_name = NULL; - - if (*name != '_') - return 0; - /* gcc 2.4 uses _vb$. */ - if (name[1] == 'v' && name[2] == 'b' && name[3] == CPLUS_MARKER) - field_class_name = name + 4; - /* gcc 2.5 will use __vb_. */ - if (name[1] == '_' && name[2] == 'v' && name[3] == 'b' && name[4] == '_') - field_class_name = name + 5; - - if (field_class_name == NULL) - /* This field is not a virtual base class pointer. */ - return 0; - - /* It's a virtual baseclass pointer, now we just need to find out whether - it is for this baseclass. */ - fieldtype = TYPE_FIELD_TYPE (type, index); - if (fieldtype == NULL - || TYPE_CODE (fieldtype) != TYPE_CODE_PTR) - /* "Can't happen". */ - return 0; - - /* What we check for is that either the types are equal (needed for - nameless types) or have the same name. This is ugly, and a more - elegant solution should be devised (which would probably just push - the ugliness into symbol reading unless we change the stabs format). */ - if (TYPE_TARGET_TYPE (fieldtype) == basetype) - return 1; - - if (TYPE_NAME (basetype) != NULL - && TYPE_NAME (TYPE_TARGET_TYPE (fieldtype)) != NULL - && STREQ (TYPE_NAME (basetype), - TYPE_NAME (TYPE_TARGET_TYPE (fieldtype)))) - return 1; - return 0; -} - -/* Compute the offset of the baseclass which is - the INDEXth baseclass of class TYPE, for a value ARG, - wih extra offset of OFFSET. - The result is the offste of the baseclass value relative - to (the address of)(ARG) + OFFSET. - - -1 is returned on error. */ - -int -baseclass_offset (type, index, arg, offset) - struct type *type; - int index; - value_ptr arg; - int offset; -{ - struct type *basetype = TYPE_BASECLASS (type, index); - - if (BASETYPE_VIA_VIRTUAL (type, index)) - { - /* Must hunt for the pointer to this virtual baseclass. */ - register int i, len = TYPE_NFIELDS (type); - register int n_baseclasses = TYPE_N_BASECLASSES (type); - - /* First look for the virtual baseclass pointer - in the fields. */ - for (i = n_baseclasses; i < len; i++) - { - if (vb_match (type, i, basetype)) - { - CORE_ADDR addr - = unpack_pointer (TYPE_FIELD_TYPE (type, i), - VALUE_CONTENTS (arg) + VALUE_OFFSET (arg) - + offset - + (TYPE_FIELD_BITPOS (type, i) / 8)); - - if (VALUE_LVAL (arg) != lval_memory) - return -1; - - return addr - - (LONGEST) (VALUE_ADDRESS (arg) + VALUE_OFFSET (arg) + offset); - } - } - /* Not in the fields, so try looking through the baseclasses. */ - for (i = index+1; i < n_baseclasses; i++) - { - int boffset = - baseclass_offset (type, i, arg, offset); - if (boffset) - return boffset; - } - /* Not found. */ - return -1; - } - - /* Baseclass is easily computed. */ - return TYPE_BASECLASS_BITPOS (type, index) / 8; -} - -/* Compute the address of the baseclass which is - the INDEXth baseclass of class TYPE. The TYPE base - of the object is at VALADDR. - - If ERRP is non-NULL, set *ERRP to be the errno code of any error, - or 0 if no error. In that case the return value is not the address - of the baseclasss, but the address which could not be read - successfully. */ - -/* FIXME Fix remaining uses of baseclass_addr to use baseclass_offset */ - -char * -baseclass_addr (type, index, valaddr, valuep, errp) - struct type *type; - int index; - char *valaddr; - value_ptr *valuep; - int *errp; -{ - struct type *basetype = TYPE_BASECLASS (type, index); - - if (errp) - *errp = 0; - - if (BASETYPE_VIA_VIRTUAL (type, index)) - { - /* Must hunt for the pointer to this virtual baseclass. */ - register int i, len = TYPE_NFIELDS (type); - register int n_baseclasses = TYPE_N_BASECLASSES (type); - - /* First look for the virtual baseclass pointer - in the fields. */ - for (i = n_baseclasses; i < len; i++) - { - if (vb_match (type, i, basetype)) - { - value_ptr val = allocate_value (basetype); - CORE_ADDR addr; - int status; - - addr - = unpack_pointer (TYPE_FIELD_TYPE (type, i), - valaddr + (TYPE_FIELD_BITPOS (type, i) / 8)); - - status = target_read_memory (addr, - VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (basetype)); - VALUE_LVAL (val) = lval_memory; - VALUE_ADDRESS (val) = addr; - - if (status != 0) - { - if (valuep) - *valuep = NULL; - release_value (val); - value_free (val); - if (errp) - *errp = status; - return (char *)addr; - } - else - { - if (valuep) - *valuep = val; - return (char *) VALUE_CONTENTS (val); - } - } - } - /* Not in the fields, so try looking through the baseclasses. */ - for (i = index+1; i < n_baseclasses; i++) - { - char *baddr; - - baddr = baseclass_addr (type, i, valaddr, valuep, errp); - if (baddr) - return baddr; - } - /* Not found. */ - if (valuep) - *valuep = 0; - return 0; - } - - /* Baseclass is easily computed. */ - if (valuep) - *valuep = 0; - return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8; -} - -/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at - VALADDR. - - Extracting bits depends on endianness of the machine. Compute the - number of least significant bits to discard. For big endian machines, - we compute the total number of bits in the anonymous object, subtract - off the bit count from the MSB of the object to the MSB of the - bitfield, then the size of the bitfield, which leaves the LSB discard - count. For little endian machines, the discard count is simply the - number of bits from the LSB of the anonymous object to the LSB of the - bitfield. - - If the field is signed, we also do sign extension. */ - -LONGEST -unpack_field_as_long (type, valaddr, fieldno) - struct type *type; - char *valaddr; - int fieldno; -{ - unsigned LONGEST val; - unsigned LONGEST valmask; - int bitpos = TYPE_FIELD_BITPOS (type, fieldno); - int bitsize = TYPE_FIELD_BITSIZE (type, fieldno); - int lsbcount; - - val = extract_unsigned_integer (valaddr + bitpos / 8, sizeof (val)); - - /* Extract bits. See comment above. */ - -#if BITS_BIG_ENDIAN - lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize); -#else - lsbcount = (bitpos % 8); -#endif - val >>= lsbcount; - - /* If the field does not entirely fill a LONGEST, then zero the sign bits. - If the field is signed, and is negative, then sign extend. */ - - if ((bitsize > 0) && (bitsize < 8 * sizeof (val))) - { - valmask = (((unsigned LONGEST) 1) << bitsize) - 1; - val &= valmask; - if (!TYPE_UNSIGNED (TYPE_FIELD_TYPE (type, fieldno))) - { - if (val & (valmask ^ (valmask >> 1))) - { - val |= ~valmask; - } - } - } - return (val); -} - -/* Modify the value of a bitfield. ADDR points to a block of memory in - target byte order; the bitfield starts in the byte pointed to. FIELDVAL - is the desired value of the field, in host byte order. BITPOS and BITSIZE - indicate which bits (in target bit order) comprise the bitfield. */ - -void -modify_field (addr, fieldval, bitpos, bitsize) - char *addr; - LONGEST fieldval; - int bitpos, bitsize; -{ - LONGEST oword; - - /* Reject values too big to fit in the field in question, - otherwise adjoining fields may be corrupted. */ - if (bitsize < (8 * sizeof (fieldval)) - && 0 != (fieldval & ~((1<= size of oword */ - if (bitsize < 8 * sizeof (oword)) - oword &= ~(((((unsigned LONGEST)1) << bitsize) - 1) << bitpos); - else - oword &= ~((~(unsigned LONGEST)0) << bitpos); - oword |= fieldval << bitpos; - - store_signed_integer (addr, sizeof oword, oword); -} - -/* Convert C numbers into newly allocated values */ - -value_ptr -value_from_longest (type, num) - struct type *type; - register LONGEST num; -{ - register value_ptr val = allocate_value (type); - register enum type_code code = TYPE_CODE (type); - register int len = TYPE_LENGTH (type); - - switch (code) - { - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_ENUM: - case TYPE_CODE_BOOL: - case TYPE_CODE_RANGE: - store_signed_integer (VALUE_CONTENTS_RAW (val), len, num); - break; - - case TYPE_CODE_REF: - case TYPE_CODE_PTR: - /* This assumes that all pointers of a given length - have the same form. */ - store_address (VALUE_CONTENTS_RAW (val), len, (CORE_ADDR) num); - break; - - default: - error ("Unexpected type encountered for integer constant."); - } - return val; -} - -value_ptr -value_from_double (type, num) - struct type *type; - double num; -{ - register value_ptr val = allocate_value (type); - register enum type_code code = TYPE_CODE (type); - register int len = TYPE_LENGTH (type); - - if (code == TYPE_CODE_FLT) - { - store_floating (VALUE_CONTENTS_RAW (val), len, num); - } - else - error ("Unexpected type encountered for floating constant."); - - return val; -} - -/* Deal with the value that is "about to be returned". */ - -/* Return the value that a function returning now - would be returning to its caller, assuming its type is VALTYPE. - RETBUF is where we look for what ought to be the contents - of the registers (in raw form). This is because it is often - desirable to restore old values to those registers - after saving the contents of interest, and then call - this function using the saved values. - struct_return is non-zero when the function in question is - using the structure return conventions on the machine in question; - 0 when it is using the value returning conventions (this often - means returning pointer to where structure is vs. returning value). */ - -value_ptr -value_being_returned (valtype, retbuf, struct_return) - register struct type *valtype; - char retbuf[REGISTER_BYTES]; - int struct_return; - /*ARGSUSED*/ -{ - register value_ptr val; - CORE_ADDR addr; - -#if defined (EXTRACT_STRUCT_VALUE_ADDRESS) - /* If this is not defined, just use EXTRACT_RETURN_VALUE instead. */ - if (struct_return) { - addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf); - if (!addr) - error ("Function return value unknown"); - return value_at (valtype, addr); - } -#endif - - val = allocate_value (valtype); - EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val)); - - return val; -} - -/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of - EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc - and TYPE is the type (which is known to be struct, union or array). - - On most machines, the struct convention is used unless we are - using gcc and the type is of a special size. */ -/* As of about 31 Mar 93, GCC was changed to be compatible with the - native compiler. GCC 2.3.3 was the last release that did it the - old way. Since gcc2_compiled was not changed, we have no - way to correctly win in all cases, so we just do the right thing - for gcc1 and for gcc2 after this change. Thus it loses for gcc - 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 \ - ) \ - )) -#endif - -/* Return true if the function specified is using the structure returning - convention on this machine to return arguments, or 0 if it is using - the value returning convention. FUNCTION is the value representing - the function, FUNCADDR is the address of the function, and VALUE_TYPE - is the type returned by the function. GCC_P is nonzero if compiled - with GCC. */ - -int -using_struct_return (function, funcaddr, value_type, gcc_p) - value_ptr function; - CORE_ADDR funcaddr; - struct type *value_type; - int gcc_p; - /*ARGSUSED*/ -{ - register enum type_code code = TYPE_CODE (value_type); - - if (code == TYPE_CODE_ERROR) - error ("Function return type unknown."); - - if (code == TYPE_CODE_STRUCT || - code == TYPE_CODE_UNION || - code == TYPE_CODE_ARRAY) - return USE_STRUCT_CONVENTION (gcc_p, value_type); - - return 0; -} - -/* Store VAL so it will be returned if a function returns now. - Does not verify that VAL's type matches what the current - function wants to return. */ - -void -set_return_value (val) - value_ptr val; -{ - register enum type_code code = TYPE_CODE (VALUE_TYPE (val)); - double dbuf; - LONGEST lbuf; - - if (code == TYPE_CODE_ERROR) - error ("Function return type unknown."); - - if ( code == TYPE_CODE_STRUCT - || code == TYPE_CODE_UNION) /* FIXME, implement struct return. */ - error ("GDB does not support specifying a struct or union return value."); - - /* FIXME, this is bogus. We don't know what the return conventions - are, or how values should be promoted.... */ - if (code == TYPE_CODE_FLT) - { - dbuf = value_as_double (val); - - STORE_RETURN_VALUE (VALUE_TYPE (val), (char *)&dbuf); - } - else - { - lbuf = value_as_long (val); - STORE_RETURN_VALUE (VALUE_TYPE (val), (char *)&lbuf); - } -} - -void -_initialize_values () -{ - add_cmd ("convenience", no_class, show_convenience, - "Debugger convenience (\"$foo\") variables.\n\ -These variables are created when you assign them values;\n\ -thus, \"print $foo=1\" gives \"$foo\" the value 1. Values may be any type.\n\n\ -A few convenience variables are given values automatically:\n\ -\"$_\"holds the last address examined with \"x\" or \"info lines\",\n\ -\"$__\" holds the contents of the last address examined with \"x\".", - &showlist); - - add_cmd ("values", no_class, show_values, - "Elements of value history around item number IDX (or last ten).", - &showlist); -} diff --git a/gnu/usr.bin/gdb/gdb/version.c b/gnu/usr.bin/gdb/gdb/version.c index 43f63d2..3d677fe 100644 --- a/gnu/usr.bin/gdb/gdb/version.c +++ b/gnu/usr.bin/gdb/gdb/version.c @@ -1,3 +1,3 @@ -char *version = "4.13"; +char *version = "4.16"; char *host_name = "i386-unknown-freebsd"; char *target_name = "i386-unknown-freebsd"; diff --git a/gnu/usr.bin/gdb/gdb/wait.h b/gnu/usr.bin/gdb/gdb/wait.h deleted file mode 100644 index 10a5eb0..0000000 --- a/gnu/usr.bin/gdb/gdb/wait.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Define how to access the int that the wait system call stores. - This has been compatible in all Unix systems since time immemorial, - but various well-meaning people have defined various different - words for the same old bits in the same old int (sometimes claimed - to be a struct). We just know it's an int and we use these macros - to access the bits. */ - -/* The following macros are defined equivalently to their definitions - in POSIX.1. We fail to define WNOHANG and WUNTRACED, which POSIX.1 - defines, since our code does not use waitpid(). We - also fail to declare wait() and waitpid(). */ - -#define WIFEXITED(w) (((w)&0377) == 0) -#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0) -#ifdef IBM6000 - -/* Unfortunately, the above comment (about being compatible in all Unix - systems) is not quite correct for AIX, sigh. And AIX 3.2 can generate - status words like 0x57c (sigtrap received after load), and gdb would - choke on it. */ - -#define WIFSTOPPED(w) ((w)&0x40) - -#else -#define WIFSTOPPED(w) (((w)&0377) == 0177) -#endif - -#define WEXITSTATUS(w) (((w) >> 8) & 0377) /* same as WRETCODE */ -#define WTERMSIG(w) ((w) & 0177) -#define WSTOPSIG WEXITSTATUS - -/* These are not defined in POSIX, but are used by our programs. */ - -#define WAITTYPE int - -#define WCOREDUMP(w) (((w)&0200) != 0) -#define WSETEXIT(w,status) ((w) = (0 | ((status) << 8))) -#define WSETSTOP(w,sig) ((w) = (0177 | ((sig) << 8))) diff --git a/gnu/usr.bin/gdb/gdb/xm.h b/gnu/usr.bin/gdb/gdb/xm.h index 6a71227..8a852a2 100644 --- a/gnu/usr.bin/gdb/gdb/xm.h +++ b/gnu/usr.bin/gdb/gdb/xm.h @@ -15,15 +15,9 @@ 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define HOST_BYTE_ORDER LITTLE_ENDIAN #include /* for INT_MIN, to avoid "INT_MIN redefined" warnings from defs.h */ - -/* psignal() is in . */ - -#define PSIGNAL_IN_SIGNAL_H - -#define HAVE_TERMIOS -- cgit v1.1