summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Shebs <shebs@apple.com>1999-04-27 01:23:18 +0000
committerStan Shebs <shebs@apple.com>1999-04-27 01:23:18 +0000
commit3ed16b22a65754c488f464cad8fc580de87b1383 (patch)
treef15fbf4059d6157f914a2dfe48e493b396bd6dd3
parent608d12d9789900f89d7f4c12e1734ab12276a493 (diff)
downloadgdb-3ed16b22a65754c488f464cad8fc580de87b1383.tar.gz
import gdb-19990422 snapshot
-rw-r--r--gdb/MAINTAINERS669
-rw-r--r--gdb/config/i386/go32.mt3
-rw-r--r--gdb/config/i386/nm-go32.h68
-rw-r--r--gdb/config/i386/tm-go32.h212
-rw-r--r--gdb/config/tic80/tic80.mt7
-rw-r--r--gdb/config/tic80/tm-tic80.h257
-rw-r--r--gdb/go32-nat.c2099
-rw-r--r--gdb/tic80-tdep.c483
8 files changed, 1482 insertions, 2316 deletions
diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS
index dd541f86e69..3810c96c1b8 100644
--- a/gdb/MAINTAINERS
+++ b/gdb/MAINTAINERS
@@ -1,636 +1,33 @@
- GDB Maintainers
- ===============
-
-
- Overview
- --------
-
-This file describes different groups of people who are, together, the
-maintainers and developers of the GDB project. Don't worry - it sounds
-more complicated than it really is.
-
-There are four groups of GDB developers, covering the patch development and
-review process:
-
- - The Global Maintainers.
-
- These are the developers in charge of most daily development. They
- have wide authority to apply and reject patches, but defer to the
- Responsible Maintainers (see below) within their spheres of
- responsibility.
-
- - The Responsible Maintainers.
-
- These are developers who have expertise and interest in a particular
- area of GDB, who are generally available to review patches, and who
- prefer to enforce a single vision within their areas.
-
- - The Authorized Committers.
-
- These are developers who are trusted to make changes within a specific
- area of GDB without additional oversight.
-
- - The Write After Approval Maintainers.
-
- These are developers who have write access to the GDB source tree. They
- can check in their own changes once a developer with the appropriate
- authority has approved the changes; they can also apply the Obvious
- Fix Rule (below).
-
-All maintainers are encouraged to post major patches to the gdb-patches
-mailing list for comments, even if they have the authority to commit the
-patch without review from another maintainer. This especially includes
-patches which change internal interfaces (e.g. global functions, data
-structures) or external interfaces (e.g. user, remote, MI, et cetera).
-
-The term "review" is used in this file to describe several kinds of feedback
-from a maintainer: approval, rejection, and requests for changes or
-clarification with the intention of approving a revised version. Review is
-a privilege and/or responsibility of various positions among the GDB
-Maintainers. Of course, anyone - whether they hold a position but not the
-relevant one for a particular patch, or are just following along on the
-mailing lists for fun, or anything in between - may suggest changes or
-ask questions about a patch!
-
-There's also a couple of other people who play special roles in the GDB
-community, separately from the patch process:
-
- - The GDB Steering Committee.
-
- These are the official (FSF-appointed) maintainers of GDB. They have
- final and overriding authority for all GDB-related decisions, including
- anything described in this file. The committee is not generally
- involved in day-to-day development (although its members may be, as
- individuals).
-
- - The Release Manager.
-
- This developer is in charge of making new releases of GDB.
-
- - The Patch Champions.
-
- These volunteers make sure that no contribution is overlooked or
- forgotten.
-
-Most changes to the list of maintainers in this file are handled by
-consensus among the global maintainers and any other involved parties.
-In cases where consensus can not be reached, the global maintainers may
-ask the Steering Committee for a final decision.
-
-
- The Obvious Fix Rule
- --------------------
-
-All maintainers listed in this file, including the Write After Approval
-developers, are allowed to check in obvious fixes.
-
-An "obvious fix" means that there is no possibility that anyone will
-disagree with the change.
-
-A good mental test is "will the person who hates my work the most be
-able to find fault with the change" - if so, then it's not obvious and
-needs to be posted first. :-)
-
-Something like changing or bypassing an interface is _not_ an obvious
-fix, since such a change without discussion will result in
-instantaneous and loud complaints.
-
-For documentation changes, about the only kind of fix that is obvious
-is correction of a typo or bad English usage.
-
-
- GDB Steering Committee
- ----------------------
-
-The members of the GDB Steering Committee are the FSF-appointed
-maintainers of the GDB project.
-
-The Steering Committee has final authority for all GDB-related topics;
-they may make whatever changes that they deem necessary, or that the FSF
-requests. However, they are generally not involved in day-to-day
-development.
-
-The current members of the steering committee are listed below, in
-alphabetical order. Their affiliations are provided for reference only -
-their membership on the Steering Committee is individual and not through
-their affiliation, and they act on behalf of the GNU project.
-
- Jim Blandy (Mozilla)
- Andrew Cagney (Red Hat)
- Robert Dewar (AdaCore, NYU)
- Klee Dienes (Apple)
- Paul Hilfinger (UC Berkeley)
- Dan Jacobowitz (CodeSourcery)
- Stan Shebs (CodeSourcery)
- Richard Stallman (FSF)
- Ian Lance Taylor (C2)
- Todd Whitesel
-
-
- Global Maintainers
- ------------------
-
-The global maintainers may review and commit any change to GDB, except in
-areas with a Responsible Maintainer available. For major changes, or
-changes to areas with other active developers, global maintainers are
-strongly encouraged to post their own patches for feedback before
-committing.
-
-The global maintainers are responsible for reviewing patches to any area
-for which no Responsible Maintainer is listed.
-
-Global maintainers also have the authority to revert patches which should
-not have been applied, e.g. patches which were not approved, controversial
-patches committed under the Obvious Fix Rule, patches with important bugs
-that can't be immediately fixed, or patches which go against an accepted and
-documented roadmap for GDB development. Any global maintainer may request
-the reversion of a patch. If no global maintainer, or responsible
-maintainer in the affected areas, supports the patch (except for the
-maintainer who originally committed it), then after 48 hours the maintainer
-who called for the reversion may revert the patch.
-
-No one may reapply a reverted patch without the agreement of the maintainer
-who reverted it, or bringing the issue to the GDB Steering Committee for
-discussion.
-
-At the moment there are no documented roadmaps for GDB development; in the
-future, if there are, a reference to the list will be included here.
-
-The current global maintainers are (in alphabetical order):
-
-Jim Blandy jimb@mozilla.com
-Joel Brobecker brobecker@adacore.com
-Kevin Buettner kevinb@redhat.com
-Andrew Cagney cagney@gnu.org
-Daniel Jacobowitz dan@debian.org
-Mark Kettenis kettenis@gnu.org
-Stan Shebs stan@codesourcery.com
-Michael Snyder msnyder@specifix.com
-Ulrich Weigand Ulrich.Weigand@de.ibm.com
-Elena Zannoni ezannoni@redhat.com
-Eli Zaretskii eliz@gnu.org
-
-
- Release Manager
- ---------------
-
-The current release manager is: Joel Brobecker <brobecker@adacore.com>
-
-His responsibilities are:
-
- * organizing, scheduling, and managing releases of GDB.
-
- * deciding the approval and commit policies for release branches,
- and can change them as needed.
-
-
-
- Patch Champions
- ---------------
-
-These volunteers track all patches submitted to the gdb-patches list. They
-endeavor to prevent any posted patch from being overlooked; work with
-contributors to meet GDB's coding style and general requirements, along with
-FSF copyright assignments; remind (ping) responsible maintainers to review
-patches; and ensure that contributors are given credit.
-
-Current patch champions (in alphabetical order):
-
- Randolph Chung <tausq@debian.org>
-
-
-
- Responsible Maintainers
- -----------------------
-
-These developers have agreed to review patches in specific areas of GDB, in
-which they have knowledge and experience. These areas are generally broad;
-the role of a responsible maintainer is to provide coherent and cohesive
-structure within their area of GDB, to assure that patches from many
-different contributors all work together for the best results.
-
-Global maintainers will defer to responsible maintainers within their areas,
-as long as the responsible maintainer is active. Active means that
-responsible maintainers agree to review submitted patches in their area
-promptly; patches and followups should generally be answered within a week.
-If a responsible maintainer is interested in reviewing a patch but will not
-have time within a week of posting, the maintainer should send an
-acknowledgement of the patch to the gdb-patches mailing list, and
-plan to follow up with a review within a month. These deadlines are for
-initial responses to a patch - if the maintainer has suggestions
-or questions, it may take an extended discussion before the patch
-is ready to commit. There are no written requirements for discussion,
-but maintainers are asked to be responsive.
-
-If a responsible maintainer misses these deadlines occasionally (e.g.
-vacation or unexpected workload), it's not a disaster - any global
-maintainer may step in to review the patch. But sometimes life intervenes
-more permanently, and a maintainer may no longer have time for these duties.
-When this happens, he or she should step down (either into the Authorized
-Committers section if still interested in the area, or simply removed from
-the list of Responsible Maintainers if not).
-
-If a responsible maintainer is unresponsive for an extended period of time
-without stepping down, please contact the Global Maintainers; they will try
-to contact the maintainer directly and fix the problem - potentially by
-removing that maintainer from their listed position.
-
-If there are several maintainers for a given domain then any one of them
-may review a submitted patch.
-
-Target Instruction Set Architectures:
-
-The *-tdep.c files. ISA (Instruction Set Architecture) and OS-ABI
-(Operating System / Application Binary Interface) issues including CPU
-variants.
-
-The Target/Architecture maintainer works with the host maintainer when
-resolving build issues. The Target/Architecture maintainer works with
-the native maintainer when resolving ABI issues.
-
- alpha --target=alpha-elf ,-Werror
-
- arm --target=arm-elf ,-Werror
- Richard Earnshaw rearnsha@arm.com
-
- avr --target=avr ,-Werror
-
- cris --target=cris-elf ,-Werror ,
- (sim does not build with -Werror)
-
- frv --target=frv-elf ,-Werror
-
- h8300 --target=h8300-elf ,-Werror
-
- i386 --target=i386-elf ,-Werror
- Mark Kettenis kettenis@gnu.org
-
- ia64 --target=ia64-linux-gnu ,-Werror
- (--target=ia64-elf broken)
-
- m32c --target=m32c-elf ,-Werror
- Jim Blandy, jimb@codesourcery.com
-
- m32r --target=m32r-elf ,-Werror
-
- m68hc11 --target=m68hc11-elf ,-Werror ,
- Stephane Carrez stcarrez@nerim.fr
-
- m68k --target=m68k-elf ,-Werror
-
- m88k --target=m88k-openbsd ,-Werror
- Mark Kettenis kettenis@gnu.org
-
- mcore Deleted
-
- mep --target=mep-elf ,-Werror
- Kevin Buettner kevinb@redhat.com
-
- mips --target=mips-elf ,-Werror
-
- mn10300 --target=mn10300-elf broken
- (sim/ dies with make -j)
- Michael Snyder msnyder@specifix.com
-
- ms1 --target=ms1-elf ,-Werror
- Kevin Buettner kevinb@redhat.com
-
- ns32k Deleted
-
- pa --target=hppa-elf ,-Werror
-
- powerpc --target=powerpc-eabi ,-Werror
-
- s390 --target=s390-linux-gnu ,-Werror
-
- score --target=score-elf
- Qinwei qinwei@sunnorth.com.cn
-
- sh --target=sh-elf ,-Werror
- --target=sh64-elf ,-Werror
-
- sparc --target=sparc64-solaris2.10 ,-Werror
- (--target=sparc-elf broken)
-
- spu --target=spu-elf ,-Werror
- Ulrich Weigand uweigand@de.ibm.com
-
- v850 --target=v850-elf ,-Werror
-
- vax --target=vax-netbsd ,-Werror
-
- x86-64 --target=x86_64-linux-gnu ,-Werror
-
- xstormy16 --target=xstormy16-elf
- Corinna Vinschen vinschen@redhat.com
-
- xtensa --target=xtensa-elf
- Maxim Grigoriev maxim2405@gmail.com
-
-All developers recognized by this file can make arbitrary changes to
-OBSOLETE targets.
-
-The Bourne shell script gdb_mbuild.sh can be used to rebuild all the
-above targets.
-
-
-Host/Native:
-
-The Native maintainer is responsible for target specific native
-support - typically shared libraries and quirks to procfs/ptrace/...
-The Native maintainer works with the Arch and Core maintainers when
-resolving more generic problems.
-
-The host maintainer ensures that gdb can be built as a cross debugger on
-their platform.
-
-AIX Joel Brobecker brobecker@adacore.com
-
-djgpp native Eli Zaretskii eliz@gnu.org
-GNU Hurd Alfred M. Szmidt ams@gnu.org
-MS Windows (NT, '00, 9x, Me, XP) host & native
- Chris Faylor cgf@alum.bu.edu
-GNU/Linux/x86 native & host
- Mark Kettenis kettenis@gnu.org
-GNU/Linux MIPS native & host
- Daniel Jacobowitz dan@debian.org
-GNU/Linux m68k Andreas Schwab schwab@suse.de
-FreeBSD native & host Mark Kettenis kettenis@gnu.org
-
-
-
-Core: Generic components used by all of GDB
-
-tracing Michael Snyder msnyder@specifix.com
-threads Michael Snyder msnyder@specifix.com
- Mark Kettenis kettenis@gnu.org
-language support
- Ada Joel Brobecker brobecker@adacore.com
- Paul Hilfinger hilfinger@gnat.com
- C++ Daniel Jacobowitz dan@debian.org
- Objective C support Adam Fedor fedor@gnu.org
-shared libs Kevin Buettner kevinb@redhat.com
-MI interface Vladimir Prus vladimir@codesourcery.com
-
-documentation Eli Zaretskii eliz@gnu.org
- (including NEWS)
-testsuite
- gdbtk (gdb.gdbtk) Keith Seitz keiths@redhat.com
- threads (gdb.threads) Michael Snyder msnyder@specifix.com
- trace (gdb.trace) Michael Snyder msnyder@specifix.com
-
-
-UI: External (user) interfaces.
-
-gdbtk (c & tcl) Fernando Nasser fnasser@redhat.com
- Keith Seitz keiths@redhat.com
-libgui (w/foundry, sn) Keith Seitz keiths@redhat.com
-
-
-Misc:
-
-gdb/gdbserver Daniel Jacobowitz dan@debian.org
-
-Makefile.in, configure* ALL
-
-mmalloc/ ALL Host maintainers
-
-sim/ See sim/MAINTAINERS
-
-readline/ Master version: ftp://ftp.cwru.edu/pub/bash/
- ALL
- Host maintainers (host dependant parts)
- (but get your changes into the master version)
-
-tcl/ tk/ itcl/ ALL
-
-
- Authorized Committers
- ---------------------
-
-These are developers working on particular areas of GDB, who are trusted to
-commit their own (or other developers') patches in those areas without
-further review from a Global Maintainer or Responsible Maintainer. They are
-under no obligation to review posted patches - but, of course, are invited
-to do so!
-
-PowerPC Andrew Cagney cagney@gnu.org
-CRIS Hans-Peter Nilsson hp@axis.com
-IA64 Jeff Johnston jjohnstn@redhat.com
-MIPS Joel Brobecker brobecker@adacore.com
-m32r Kei Sakamoto sakamoto.kei@renesas.com
-PowerPC Kevin Buettner kevinb@redhat.com
-CRIS Orjan Friberg orjanf@axis.com
-HPPA Randolph Chung tausq@debian.org
-S390 Ulrich Weigand uweigand@de.ibm.com
-djgpp DJ Delorie dj@delorie.com
- [Please use this address to contact DJ about DJGPP]
-tui Stephane Carrez stcarrez@nerim.fr
-ia64 Kevin Buettner kevinb@redhat.com
-AIX Kevin Buettner kevinb@redhat.com
-GNU/Linux PPC native Kevin Buettner kevinb@redhat.com
-gdb.java tests Anthony Green green@redhat.com
-FreeBSD native & host David O'Brien obrien@freebsd.org
-event loop Elena Zannoni ezannoni@redhat.com
-generic symtabs Elena Zannoni ezannoni@redhat.com
-dwarf readers Elena Zannoni ezannoni@redhat.com
-elf reader Elena Zannoni ezannoni@redhat.com
-stabs reader Elena Zannoni ezannoni@redhat.com
-readline/ Elena Zannoni ezannoni@redhat.com
-NetBSD native & host Jason Thorpe thorpej@netbsd.org
-Pascal support Pierre Muller muller@sources.redhat.com
-avr Theodore A. Roth troth@openavr.org
-Modula-2 support Gaius Mulley gaius@glam.ac.uk
-
-
- Write After Approval
- (alphabetic)
-
-To get recommended for the Write After Approval list you need a valid
-FSF assignment and have submitted one good patch.
-
-Pedro Alves pedro_alves@portugalmail.pt
-David Anderson davea@sgi.com
-John David Anglin dave.anglin@nrc-cnrc.gc.ca
-Shrinivas Atre shrinivasa@kpitcummins.com
-Scott Bambrough scottb@netwinder.org
-Thiago Jung Bauermann bauerman@br.ibm.com
-Jan Beulich jbeulich@novell.com
-Jim Blandy jimb@codesourcery.com
-Philip Blundell philb@gnu.org
-Per Bothner per@bothner.com
-Joel Brobecker brobecker@adacore.com
-Dave Brolley brolley@redhat.com
-Paul Brook paul@codesourcery.com
-Julian Brown julian@codesourcery.com
-Kevin Buettner kevinb@redhat.com
-Andrew Cagney cagney@gnu.org
-David Carlton carlton@bactrian.org
-Stephane Carrez stcarrez@nerim.fr
-Michael Chastain mec.gnu@mindspring.com
-Eric Christopher echristo@apple.com
-Randolph Chung tausq@debian.org
-Nick Clifton nickc@redhat.com
-J.T. Conklin jtc@acorntoolworks.com
-Brendan Conoboy blc@redhat.com
-Ludovic Courtès ludo@gnu.org
-DJ Delorie dj@redhat.com
-Chris Demetriou cgd@google.com
-Philippe De Muyter phdm@macqel.be
-Dhananjay Deshpande dhananjayd@kpitcummins.com
-Markus Deuling deuling@de.ibm.com
-Klee Dienes kdienes@apple.com
-Gabriel Dos Reis gdr@integrable-solutions.net
-Richard Earnshaw rearnsha@arm.com
-Steve Ellcey sje@cup.hp.com
-Frank Ch. Eigler fche@redhat.com
-Ben Elliston bje@gnu.org
-Doug Evans dje@google.com
-Adam Fedor fedor@gnu.org
-Brian Ford ford@vss.fsi.com
-Orjan Friberg orjanf@axis.com
-Nathan Froyd froydnj@codesourcery.com
-Gary Funck gary@intrepid.com
-Paul Gilliam pgilliam@us.ibm.com
-Raoul Gough RaoulGough@yahoo.co.uk
-Anthony Green green@redhat.com
-Matthew Green mrg@eterna.com.au
-Maxim Grigoriev maxim2405@gmail.com
-Jerome Guitton guitton@act-europe.fr
-Ben Harris bjh21@netbsd.org
-Richard Henderson rth@redhat.com
-Aldy Hernandez aldyh@redhat.com
-Paul Hilfinger hilfinger@gnat.com
-Matt Hiller hiller@redhat.com
-Kazu Hirata kazu@cs.umass.edu
-Jeff Holcomb jeffh@redhat.com
-Don Howard dhoward@redhat.com
-Nick Hudson nick.hudson@dsl.pipex.com
-Martin Hunt hunt@redhat.com
-Jim Ingham jingham@apple.com
-Baurzhan Ismagulov ibr@radix50.net
-Manoj Iyer manjo@austin.ibm.com
-Daniel Jacobowitz dan@debian.org
-Andreas Jaeger aj@suse.de
-Jeff Johnston jjohnstn@redhat.com
-Geoff Keating geoffk@redhat.com
-Mark Kettenis kettenis@gnu.org
-Marc Khouzam marc.khouzam@ericsson.com
-Jim Kingdon kingdon@panix.com
-Jan Kratochvil jan.kratochvil@redhat.com
-Jonathan Larmour jlarmour@redhat.co.uk
-Jeff Law law@redhat.com
-David Lecomber david@streamline-computing.com
-Robert Lipe rjl@sco.com
-H.J. Lu hjl.tools@gmail.com
-Michal Ludvig mludvig@suse.cz
-Luis Machado luisgpm@br.ibm.com
-Glen McCready gkm@redhat.com
-Greg McGary greg@mcgary.org
-Roland McGrath roland@redhat.com
-Bryce McKinlay mckinlay@redhat.com
-Jason Merrill jason@redhat.com
-David S. Miller davem@redhat.com
-Mark Mitchell mark@codesourcery.com
-Marko Mlinar markom@opencores.org
-Alan Modra amodra@bigpond.net.au
-Jason Molenda jmolenda@apple.com
-Pierre Muller muller@sources.redhat.com
-Gaius Mulley gaius@glam.ac.uk
-Joseph Myers joseph@codesourcery.com
-Fernando Nasser fnasser@redhat.com
-Adam Nemet anemet@caviumnetworks.com
-Nathanael Nerode neroden@gcc.gnu.org
-Hans-Peter Nilsson hp@bitrange.com
-David O'Brien obrien@freebsd.org
-Alexandre Oliva aoliva@redhat.com
-Denis Pilat denis.pilat@st.com
-Vladimir Prus vladimir@codesourcery.com
-Qinwei qinwei@sunnorth.com.cn
-Frederic Riss frederic.riss@st.com
-Aleksandar Ristovski aristovski@qnx.com
-Tom Rix trix@redhat.com
-Nick Roberts nickrob@snap.net.nz
-Bob Rossi bob_rossi@cox.net
-Theodore A. Roth troth@openavr.org
-Ian Roxborough irox@redhat.com
-Maciej W. Rozycki macro@linux-mips.org
-Grace Sainsbury graces@redhat.com
-Kei Sakamoto sakamoto.kei@renesas.com
-Mark Salter msalter@redhat.com
-Richard Sandiford richard@codesourcery.com
-Peter Schauer Peter.Schauer@mytum.de
-Andreas Schwab schwab@suse.de
-Keith Seitz keiths@redhat.com
-Carlos Eduardo Seo cseo@linux.vnet.ibm.com
-Stan Shebs stan@codesourcery.com
-Mark Shinwell shinwell@codesourcery.com
-Craig Silverstein csilvers@google.com
-Aidan Skinner aidan@velvet.net
-Jiri Smid smid@suse.cz
-David Smith dsmith@redhat.com
-Stephen P. Smith ischis2@cox.net
-Jackie Smith Cashion jsmith@redhat.com
-Michael Snyder msnyder@specifix.com
-Petr Sorfa petrs@caldera.com
-Andrew Stubbs andrew.stubbs@st.com
-Ian Lance Taylor ian@airs.com
-Gary Thomas gthomas@redhat.com
-Jason Thorpe thorpej@netbsd.org
-Caroline Tice ctice@apple.com
-Tom Tromey tromey@redhat.com
-David Ung davidu@mips.com
-D Venkatasubramanian dvenkat@noida.hcltech.com
-Corinna Vinschen vinschen@redhat.com
-Keith Walker keith.walker@arm.com
-Kris Warkentin kewarken@qnx.com
-Ulrich Weigand uweigand@de.ibm.com
-Nathan Williams nathanw@wasabisystems.com
-Bob Wilson bob.wilson@acm.org
-Jim Wilson wilson@tuliptree.org
-Elena Zannoni ezannoni@redhat.com
-Eli Zaretskii eliz@gnu.org
-Wu Zhou woodzltc@cn.ibm.com
-Yoshinori Sato ysato@users.sourceforge.jp
-Hui Zhu teawater@gmail.com
-
-
- Past Maintainers
-
-Whenever removing yourself, or someone else, from this file, consider
-listing their areas of development here for posterity.
-
-Jimmy Guo (gdb.hp, tui) guo at cup dot hp dot com
-Jeff Law (hppa) law at cygnus dot com
-Daniel Berlin (C++ support) dan at cgsoftware dot com
-Nick Duffek (powerpc, SCO, Sol/x86) nick at duffek dot com
-David Taylor (d10v, sparc, utils, defs,
- expression evaluator, language support) taylor at candd dot org
-J.T. Conklin (dcache, NetBSD, remote, global) jtc at acorntoolworks dot com
-Frank Ch. Eigler (sim) fche at redhat dot com
-Per Bothner (Java) per at bothner dot com
-Anthony Green (Java) green at redhat dot com
-Fernando Nasser (testsuite/, mi, cli, KOD) fnasser at redhat dot com
-Mark Salter (testsuite/lib+config) msalter at redhat dot com
-Jim Kingdon (web pages) kingdon at panix dot com
-Jim Ingham (gdbtk, libgui) jingham at apple dot com
-Mark Kettenis (hurd native) kettenis at gnu dot org
-Ian Roxborough (in-tree tcl, tk, itcl) irox at redhat dot com
-Robert Lipe (SCO/Unixware) rjl at sco dot com
-Peter Schauer (global, AIX, xcoffsolib,
- Solaris/x86) Peter.Schauer at mytum dot de
-Scott Bambrough (ARM) scottb at netwinder dot org
-Philippe De Muyter (coff) phdm at macqel dot be
-Michael Chastain (testsuite) mec.gnu at mindspring dot com
-Fred Fish (global)
-
-
-
-Folks that have been caught up in a paper trail:
-
-David Carlton carlton@bactrian.org
-Ramana Radhakrishnan ramana.r@gmail.com
-
-;; Local Variables:
-;; coding: utf-8
-;; End:
+d10v target Andrew Cagney cagney@cygnus.com
+d30v target Andrew Cagney cagney@cygnus.com
+mips target Andrew Cagney cagney@cygnus.com
+powerpc target Andrew Cagney cagney@cygnus.com
+generic arch support Andrew Cagney cagney@cygnus.com
+target vector Andrew Cagney cagney@cygnus.com
+remote.c Andrew Cagney cagney@cygnus.com
+djgpp native DJ Delorie dj@cygnus.com
+win32 host & native Chris Faylor cgf@cygnus.com
+main (main.c, top.c) Elena Zannoni ezannoni@cygnus.com
+readline Elena Zannoni ezannoni@cygnus.com
+arm target Elena Zannoni ezannoni@cygnus.com
+command interpreter Fernando Nasser fnasser@cygnus.com
+generic symtabs Jim Blandy jimb@cygnus.com
+dwarf readers Jim Blandy jimb@cygnus.com
+elf reader Jim Blandy jimb@cygnus.com
+stabs reader Jim Blandy jimb@cygnus.com
+x86 linux native Jim Blandy jimb@cygnus.com
+Scheme support Jim Blandy jimb@cygnus.com
+m32r target Michael Snyder msnyder@cygnus.com
+tracing Michael Snyder msnyder@cygnus.com
+threads Michael Snyder msnyder@cygnus.com
+breakpoint.c Michael Snyder msnyder@cygnus.com
+macos host & native Stan Shebs shebs@cygnus.com
+sds protocol Stan Shebs shebs@cygnus.com
+rdi/adp protocol Stan Shebs shebs@cygnus.com
+gdbserver Stan Shebs shebs@cygnus.com
+documentation Stan Shebs shebs@cygnus.com
+testsuite Stan Shebs shebs@cygnus.com
+language support David Taylor taylor@cygnus.com
+expression eval David Taylor taylor@cygnus.com
+defs.h David Taylor taylor@cygnus.com
+utils.c David Taylor taylor@cygnus.com
diff --git a/gdb/config/i386/go32.mt b/gdb/config/i386/go32.mt
new file mode 100644
index 00000000000..9b82c6426b4
--- /dev/null
+++ b/gdb/config/i386/go32.mt
@@ -0,0 +1,3 @@
+# Target: Intel 386 running DJGPP
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-go32.h
diff --git a/gdb/config/i386/nm-go32.h b/gdb/config/i386/nm-go32.h
index 86ed270f7d7..183b60fa181 100644
--- a/gdb/config/i386/nm-go32.h
+++ b/gdb/config/i386/nm-go32.h
@@ -1,35 +1,57 @@
/* Native definitions for Intel x86 running DJGPP.
- Copyright 1997, 1998, 1999, 2001, 2002, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
- This file is part of GDB.
+This file is part of GDB.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#define I386_USE_GENERIC_WATCHPOINTS
+#define NO_PTRACE_H
-#include "i386/nm-i386.h"
+#include "i386/nm-i386v.h"
-/* Support for hardware-assisted breakpoints and watchpoints. */
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
-#define I386_DR_LOW_SET_CONTROL(VAL) go32_set_dr7 (VAL)
-extern void go32_set_dr7 (unsigned);
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
-#define I386_DR_LOW_SET_ADDR(N,ADDR) go32_set_dr (N,ADDR)
-extern void go32_set_dr (int, CORE_ADDR);
+/* After a watchpoint trap, the PC points to the instruction after the
+ one that caused the trap. Therefore we don't need to step over it.
+ But we do need to reset the status register to avoid another trap. */
-#define I386_DR_LOW_RESET_ADDR(N)
+#define HAVE_CONTINUABLE_WATCHPOINT
+
+#define STOPPED_BY_WATCHPOINT(W) \
+ go32_stopped_by_watchpoint (inferior_pid)
+
+/* Use these macros for watchpoint insertion/removal. */
+
+#define target_insert_watchpoint(addr, len, type) \
+ go32_insert_watchpoint (inferior_pid, addr, len, 2)
+
+#define target_remove_watchpoint(addr, len, type) \
+ go32_remove_watchpoint (inferior_pid, addr, len)
+
+#define target_insert_hw_breakpoint(addr, shadow) \
+ go32_insert_hw_breakpoint(addr, shadow)
+
+#define target_remove_hw_breakpoint(addr, shadow) \
+ go32_remove_hw_breakpoint(addr, shadow)
+
+#define DECR_PC_AFTER_HW_BREAK 0
+
+#undef FLOAT_INFO
+#define FLOAT_INFO { i386_go32_float_info (); }
+
+extern void i386_go32_float_info (void);
-#define I386_DR_LOW_GET_STATUS() go32_get_dr6 ()
-extern unsigned go32_get_dr6 (void);
diff --git a/gdb/config/i386/tm-go32.h b/gdb/config/i386/tm-go32.h
new file mode 100644
index 00000000000..84b82929ec5
--- /dev/null
+++ b/gdb/config/i386/tm-go32.h
@@ -0,0 +1,212 @@
+/* Target-dependent definitions for Intel x86 running DJGPP.
+ Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "i386/tm-i386v.h"
+
+/* Number of machine registers. */
+
+#undef NUM_FREGS
+#define NUM_FREGS 15
+#undef NUM_REGS
+#define NUM_REGS (16+NUM_FREGS)
+
+/* 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). */
+
+#undef REGISTER_NAMES
+#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \
+ "esp", "ebp", "esi", "edi", \
+ "eip", "eflags","cs", "ss", \
+ "ds", "es", "fs", "gs", \
+ "st0", "st1", "st2", "st3", \
+ "st4", "st5", "st6", "st7", \
+ "fctrl","fstat", "ftag", "fcs", \
+ "fopsel","fip", "fopoff" }
+
+#undef FP_REGNUM
+#define FP_REGNUM 5 /* (ebp) Contains addr of stack frame */
+#undef SP_REGNUM
+#define SP_REGNUM 4 /* (usp) Contains address of top of stack */
+#undef PS_REGNUM
+#define PS_REGNUM 9 /* (ps) Contains processor status */
+#undef PC_REGNUM
+#define PC_REGNUM 8 /* (eip) Contains program counter */
+#undef FP0_REGNUM
+#define FP0_REGNUM 16 /* Floating point register 0 */
+#undef FPC_REGNUM
+#define FPC_REGNUM 24 /* 80387 control register */
+#undef FPCWD_REGNUM
+#define FPCWD_REGNUM FPC_REGNUM
+#undef FPSWD_REGNUM
+#define FPSWD_REGNUM 25 /* 80387 status register */
+#undef FPTWD_REGNUM
+#define FPTWD_REGNUM 26 /* 80387 tag register */
+#undef FPIPO_REGNUM
+#define FPIPO_REGNUM 29 /* 80387 instruction pointer offset reg */
+#undef FPIPS_REGNUM
+#define FPIPS_REGNUM 27 /* 80387 instruction pointer selector reg */
+#undef FPOOS_REGNUM
+#define FPOOS_REGNUM 30 /* 80387 operand pointer offset reg */
+#undef FPOPS_REGNUM
+#define FPOPS_REGNUM 28 /* 80387 operand pointer selector reg */
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+
+#undef REGISTER_BYTES
+#define REGISTER_BYTES (10*4 + 6*2 + 8*10 + 5*2 + 2*4)
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#undef REGISTER_BYTE
+#define REGBYTE_0 0
+#define REGBYTE_10 (REGBYTE_0+10*4)
+#define REGBYTE_16 (REGBYTE_10+6*2)
+#define REGBYTE_24 (REGBYTE_16+8*10)
+#define REGBYTE_29 (REGBYTE_24+5*2)
+#define REGISTER_BYTE(N) (((N) < 10) ? (N) * 4 : \
+ (N) < 16 ? REGBYTE_10 +((N) - 10) * 2 : \
+ (N) < 24 ? REGBYTE_16 +((N) - 16) * 10 : \
+ (N) < 29 ? REGBYTE_24 +((N) - 24) * 2 : \
+ REGBYTE_29 + ((N) - 29) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+ for register N. */
+
+#undef REGISTER_RAW_SIZE
+#define REGISTER_RAW_SIZE(N) ((N) < 10 ? 4 : (N) < 16 ? 2 : (N) < 24 ? 10 : \
+ (N) < 29 ? 2 : 4)
+
+/* Number of bytes of storage in the program's representation
+ for register N. */
+
+#undef REGISTER_VIRTUAL_SIZE
+#define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#undef MAX_REGISTER_RAW_SIZE
+#define MAX_REGISTER_RAW_SIZE 10
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#undef MAX_REGISTER_VIRTUAL_SIZE
+#define MAX_REGISTER_VIRTUAL_SIZE 10
+
+/* Nonzero if register N requires conversion
+ from raw format to virtual format. */
+
+#undef REGISTER_CONVERTIBLE
+#define REGISTER_CONVERTIBLE(N) ((N) < FP0_REGNUM ? 0 :\
+ (N) < FPC_REGNUM ? 1 : 0)
+
+/* The host and target are i386 machines and the compiler supports
+ long doubles. Long doubles on the host therefore have the same
+ layout as a 387 FPU stack register. */
+
+#if defined(HAVE_LONG_DOUBLE) && defined(HOST_I386)
+#undef LD_I387
+#define LD_I387
+#endif
+
+/* Allow floating point numbers to be specified by a raw long double
+ 10 hex bytes number, e.g. 1.0 can be input as
+ 0x3fff8000000000000000 */
+
+#ifdef LD_I387
+#define HEX_LONG_DOUBLE_INPUT(base,p,len,target) \
+ ((base) == 16 && (len) == 20 \
+ && i387_hex_long_double_input ((p), (target)))
+#endif
+
+extern int i387_hex_long_double_input (char *p, long double *putithere);
+
+#undef REGISTER_CONVERT_TO_VIRTUAL
+#ifdef LD_I387
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
+{ \
+ if (TYPE == REGISTER_VIRTUAL_TYPE (REGNUM)) \
+ { \
+ memcpy (TO, FROM, TYPE_LENGTH (TYPE)); \
+ } \
+ else \
+ { \
+ long double val = *((long double *)FROM); \
+ store_floating ((TO), TYPE_LENGTH (TYPE), val); \
+ } \
+}
+#else
+/* Convert data from raw format for register REGNUM in buffer FROM to
+ virtual format with type TYPE in buffer TO. */
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
+{ \
+ double val; \
+ i387_to_double ((FROM), (char *)&val); \
+ store_floating ((TO), TYPE_LENGTH (TYPE), val); \
+}
+#endif
+
+extern void i387_to_double PARAMS ((char *, char *));
+
+#undef REGISTER_CONVERT_TO_RAW
+#ifdef LD_I387
+#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
+{ \
+ if (TYPE == REGISTER_VIRTUAL_TYPE (REGNUM)) \
+ { \
+ memcpy (TO, FROM, TYPE_LENGTH (TYPE)); \
+ } \
+ else \
+ { \
+ long double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
+ *((long double *)TO) = val; \
+ } \
+}
+#else
+#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
+{ \
+ double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
+ double_to_i387((char *)&val, (TO)); \
+}
+#endif
+
+extern void double_to_i387 PARAMS ((char *, char *));
+
+/* Return the GDB type object for the "standard" data type of data in
+ register N. */
+
+#undef REGISTER_VIRTUAL_TYPE
+#ifdef LD_I387
+#define REGISTER_VIRTUAL_TYPE(N) \
+ ((N < FP0_REGNUM) ? builtin_type_int : \
+ (N < FPC_REGNUM) ? builtin_type_long_double : builtin_type_int)
+#else
+#define REGISTER_VIRTUAL_TYPE(N) \
+ ((N < FP0_REGNUM) ? builtin_type_int : \
+ (N < FPC_REGNUM) ? builtin_type_double : builtin_type_int)
+#endif
+
+#undef TARGET_LONG_DOUBLE_BIT
+#define TARGET_LONG_DOUBLE_BIT 96
+
+#define NAMES_HAVE_UNDERSCORE
diff --git a/gdb/config/tic80/tic80.mt b/gdb/config/tic80/tic80.mt
new file mode 100644
index 00000000000..10be27e2633
--- /dev/null
+++ b/gdb/config/tic80/tic80.mt
@@ -0,0 +1,7 @@
+# Target: TI TMS320C80 (MVP) processor
+TDEPFILES= tic80-tdep.o
+TM_FILE= tm-tic80.h
+SIM_OBS = remote-sim.o
+SIM = ../sim/tic80/libsim.a
+GDBSERVER_DEPFILES= low-sim.o
+GDBSERVER_LIBS = ../../sim/tic80/libsim.a ../../bfd/libbfd.a ../../libiberty/libiberty.a -lm
diff --git a/gdb/config/tic80/tm-tic80.h b/gdb/config/tic80/tm-tic80.h
new file mode 100644
index 00000000000..e17ca95b838
--- /dev/null
+++ b/gdb/config/tic80/tm-tic80.h
@@ -0,0 +1,257 @@
+/* Parameters for execution on a TI TMS320C80 (MVP) processor.
+ Copyright 1997
+ Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef TM_TIC80_H
+#define TM_TIC80_H
+
+#ifdef __STDC__ /* Forward declare structs used in prototypes */
+struct frame_info;
+struct type;
+struct value;
+struct symbol;
+struct frame_saved_regs;
+#endif
+
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+
+/* Define this if the C compiler puts an underscore at the front
+ of external names before giving them to the linker. */
+
+#define NAMES_HAVE_UNDERSCORE
+
+#define NUM_REGS 38
+
+#define REGISTER_NAMES \
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
+ "pc", "npc", \
+ "a0", "a1", "a2", "a3", \
+}
+
+/* Various dedicated register numbers
+ FIXME: Shadow updates in sim/tic80/sim-calls.c */
+
+#define SP_REGNUM 1 /* Contains address of top of stack */
+#define ARG0_REGNUM 2 /* Contains argument 1 (r3 has high word) */
+#define RET_REGNUM 2 /* Contains function return value */
+#define ARGLAST_REGNUM 12 /* Contains argument 6 (r13 has high word) */
+#define FP_REGNUM 30 /* Contains address of executing stack frame */
+#define LR_REGNUM 31 /* Contains address of caller (link register) */
+#define PC_REGNUM 32 /* Contains program counter (FIXME?) */
+#define NPC_REGNUM 33 /* Contains the next program counter (FIXME?) */
+#define A0_REGNUM 34 /* Accumulator register 0 */
+#define A3_REGNUM 37 /* Accumulator register 1 */
+
+#define R0_REGNUM 0 /* General Purpose Register 0 - for sim */
+#define Rn_REGNUM 31 /* Last General Purpose Register - for sim */
+#define An_REGNUM A3_REGNUM /* Last Accumulator register - for sim */
+
+/* Total amount of space needed to store our copies of the machine's
+ register state, the array `registers'. */
+
+#define REGISTER_BYTES (((NUM_REGS - 4) * 4) + (4 * 8))
+
+/* Index within `registers' of the first byte of the space for
+ register N. */
+
+#define REGISTER_BYTE(N) \
+ (((N) >= A0_REGNUM) ? (((N) - A0_REGNUM) * 8 + A0_REGNUM * 4) : ((N) * 4))
+
+/* Most registers are 4 bytes */
+
+#define REGISTER_SIZE 4
+
+/* Some registers are 8 bytes. */
+
+#define REGISTER_RAW_SIZE(N) \
+ (((N) >= A0_REGNUM) ? 8 : 4)
+
+/* Largest value REGISTER_RAW_SIZE can have. */
+
+#define MAX_REGISTER_RAW_SIZE (8)
+
+/* All regs are 4 bytes. */
+
+#define REGISTER_VIRTUAL_SIZE(N) (REGISTER_RAW_SIZE(N))
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+
+#define MAX_REGISTER_VIRTUAL_SIZE (MAX_REGISTER_RAW_SIZE)
+
+/* Return the GDB type object for the "standard" data type
+ of data in register N. */
+
+#define REGISTER_VIRTUAL_TYPE(N) /* FIXME? */ \
+ (((N) >= A0_REGNUM) ? builtin_type_float : builtin_type_int)
+
+/* Offset from address of function to start of its code.
+ Zero on most machines. */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Stack grows downward. */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* Sequence of bytes for breakpoint instruction.
+ This is padded out to the size of a machine word. */
+
+#define BREAKPOINT {0x49, 0x80, 0x00, 0x00} /* FIXME! */
+
+/* Amount PC must be decremented by after a breakpoint.
+ This is often the number of bytes in BREAKPOINT
+ but not always. */
+
+#define DECR_PC_AFTER_BREAK 0 /* FIXME! */
+
+/* Discard from the stack the innermost frame, restoring all registers. */
+
+#define POP_FRAME tic80_pop_frame(get_current_frame ())
+extern struct frame_info *tic80_pop_frame PARAMS ((struct frame_info *frame));
+
+/* Return number of bytes at start of arglist that are not really args. */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Set VAL to the number of args passed to frame described by FI.
+ Can set VAL to -1, meaning no way to tell. */
+/* We can't tell how many args there are */
+
+#define FRAME_NUM_ARGS(val,fi) (val = -1)
+
+#define FRAME_ARGS_SKIP 0
+#define FRAME_ARGS_ADDRESS(fi) (fi)->frame
+#define FRAME_LOCALS_ADDRESS(fi) (fi)->frame
+
+/* Define other aspects of the stack frame.
+ We keep the offsets of all saved registers, 'cause we need 'em a lot!
+ We also keep the current size of the stack frame, and the offset of
+ the frame pointer from the stack pointer (for frameless functions, and
+ when we're still in the prologue of a function with a frame) */
+
+#define EXTRA_FRAME_INFO \
+ struct frame_saved_regs fsr; \
+ int framesize; \
+ int frameoffset; \
+ int framereg;
+
+extern void tic80_init_extra_frame_info PARAMS ((struct frame_info *fi));
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) tic80_init_extra_frame_info (fi)
+#define INIT_FRAME_PC /* Not necessary */
+
+/* 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) \
+ tic80_frame_find_saved_regs(frame_info, &(frame_saved_regs))
+extern void tic80_frame_find_saved_regs PARAMS ((struct frame_info *, struct frame_saved_regs *));
+
+/* Advance PC across any function entry prologue instructions
+ to reach some "real" code. */
+
+#define SKIP_PROLOGUE(pc) { (pc) = tic80_skip_prologue (pc); }
+extern CORE_ADDR tic80_skip_prologue PARAMS ((CORE_ADDR pc));
+
+/* 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_register (LR_REGNUM)
+
+/* Describe the pointer in each stack frame to the previous stack frame
+ (its caller). */
+
+/* FRAME_CHAIN takes a frame's nominal address
+ and produces the frame's chain-pointer. */
+
+#define FRAME_CHAIN(thisframe) (CORE_ADDR) tic80_frame_chain (thisframe)
+extern CORE_ADDR tic80_frame_chain PARAMS ((struct frame_info *));
+
+#define FRAME_SAVED_PC(FRAME) tic80_frame_saved_pc (FRAME)
+extern CORE_ADDR tic80_frame_saved_pc PARAMS ((struct frame_info *));
+
+/* Store the address of the place in which to copy the structure the
+ subroutine will return. This is called from call_function.
+
+ We store structs through a pointer passed in R2 */
+
+#define STORE_STRUCT_RETURN(STRUCT_ADDR, SP) \
+ write_register (ARG0_REGNUM, STRUCT_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), \
+ (char *)(REGBUF) + REGISTER_BYTE (RET_REGNUM) + \
+ ((TYPE_LENGTH (TYPE) > 4 ? 8 : 4) - TYPE_LENGTH (TYPE)), \
+ 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(REGISTER_BYTE (RET_REGNUM) + \
+ ((TYPE_LENGTH (TYPE) > 4 ? 8:4) - TYPE_LENGTH (TYPE)),\
+ (VALBUF), TYPE_LENGTH (TYPE));
+
+
+
+/* PUSH_ARGUMENTS */
+extern CORE_ADDR tic80_push_arguments PARAMS ((int nargs,
+ struct value **args,
+ CORE_ADDR sp,
+ unsigned char struct_return,
+ CORE_ADDR struct_addr));
+
+#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
+ (SP) = tic80_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)
+
+/* PUSH_RETURN_ADDRESS */
+extern CORE_ADDR tic80_push_return_address PARAMS ((CORE_ADDR, CORE_ADDR));
+#define PUSH_RETURN_ADDRESS(PC, SP) tic80_push_return_address (PC, SP)
+
+/* override the standard get_saved_register function with
+ one that takes account of generic CALL_DUMMY frames */
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \
+ generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+
+#define USE_GENERIC_DUMMY_FRAMES 1
+#define CALL_DUMMY {0}
+#define CALL_DUMMY_LENGTH (0)
+#define CALL_DUMMY_START_OFFSET (0)
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+#define FIX_CALL_DUMMY(DUMMY1, STARTADDR, FUNADDR, NARGS, ARGS, TYPE, GCCP)
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+#define CALL_DUMMY_ADDRESS() entry_point_address ()
+
+/* generic dummy frame stuff */
+
+#define PUSH_DUMMY_FRAME generic_push_dummy_frame ()
+#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP)
+
+#endif /* TM_TIC80_H */
diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c
index d4744a8b5c4..782d240805b 100644
--- a/gdb/go32-nat.c
+++ b/gdb/go32-nat.c
@@ -1,302 +1,214 @@
/* Native debugging support for Intel x86 running DJGPP.
- Copyright (C) 1997, 1999, 2000, 2001, 2005, 2006, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright 1997, 1999 Free Software Foundation, Inc.
Written by Robert Hoehne.
- This file is part of GDB.
+This file is part of GDB.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+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 <fcntl.h>
#include "defs.h"
+#include "frame.h" /* required by inferior.h */
#include "inferior.h"
-#include "gdb_wait.h"
+#include "target.h"
+#include "wait.h"
#include "gdbcore.h"
#include "command.h"
-#include "gdbcmd.h"
#include "floatformat.h"
-#include "buildsym.h"
-#include "i387-tdep.h"
-#include "i386-tdep.h"
-#include "value.h"
-#include "regcache.h"
-#include "gdb_string.h"
-#include "top.h"
-
-#include <stdio.h> /* might be required for __DJGPP_MINOR__ */
+
#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
+#include <string.h>
#include <unistd.h>
-#include <sys/utsname.h>
-#include <io.h>
-#include <dos.h>
-#include <dpmi.h>
-#include <go32.h>
-#include <sys/farptr.h>
#include <debug/v2load.h>
#include <debug/dbgcom.h>
-#if __DJGPP_MINOR__ > 2
-#include <debug/redir.h>
-#endif
-#if __DJGPP_MINOR__ < 3
-/* This code will be provided from DJGPP 2.03 on. Until then I code it
- here */
-typedef struct
- {
- unsigned short sig0;
- unsigned short sig1;
- unsigned short sig2;
- unsigned short sig3;
- unsigned short exponent:15;
- unsigned short sign:1;
- }
-NPXREG;
+extern void _initialize_go32_nat (void);
+
+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];
+};
-typedef struct
- {
- unsigned int control;
- unsigned int status;
- unsigned int tag;
- unsigned int eip;
- unsigned int cs;
- unsigned int dataptr;
- unsigned int datasel;
- NPXREG reg[8];
- }
-NPX;
+extern char **environ;
-static NPX npx;
+#define SOME_PID 42
-static void save_npx (void); /* Save the FPU of the debugged program */
-static void load_npx (void); /* Restore the FPU of the debugged program */
+/* FIXME add decls of all static functions here */
-/* ------------------------------------------------------------------------- */
-/* Store the contents of the NPX in the global variable `npx'. */
-/* *INDENT-OFF* */
+static int prog_has_started = 0;
static void
-save_npx (void)
+print_387_status (unsigned short status, struct env387 *ep)
{
- asm ("inb $0xa0, %%al \n\
- testb $0x20, %%al \n\
- jz 1f \n\
- xorb %%al, %%al \n\
- outb %%al, $0xf0 \n\
- movb $0x20, %%al \n\
- outb %%al, $0xa0 \n\
- outb %%al, $0x20 \n\
-1: \n\
- fnsave %0 \n\
- fwait "
-: "=m" (npx)
-: /* No input */
-: "%eax");
-}
+ int i;
+ int bothstatus;
+ int top;
+ int fpreg;
-/* *INDENT-ON* */
+ bothstatus = ((status != 0) && (ep->status != 0));
+ if (status != 0)
+ {
+ if (bothstatus)
+ printf_unfiltered ("u: ");
+ print_387_status_word (status);
+ }
+ if (ep->status != 0)
+ {
+ if (bothstatus)
+ printf_unfiltered ("e: ");
+ print_387_status_word (ep->status);
+ }
-/* ------------------------------------------------------------------------- */
-/* Reload the contents of the NPX from the global variable `npx'. */
+ print_387_control_word (ep->control & 0xffff);
+ printf_unfiltered ("last exception: ");
+ printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode));
+ printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
+ printf_unfiltered ("%s; ", local_hex_string (ep->eip));
+ printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
+ printf_unfiltered (":%s\n", local_hex_string (ep->operand));
-static void
-load_npx (void)
-{
- asm ("frstor %0":"=m" (npx));
-}
-/* ------------------------------------------------------------------------- */
-/* Stubs for the missing redirection functions. */
-typedef struct {
- char *command;
- int redirected;
-} cmdline_t;
+ top = (ep->status >> 11) & 7;
-void
-redir_cmdline_delete (cmdline_t *ptr)
-{
- ptr->redirected = 0;
-}
+ printf_unfiltered ("regno tag msb lsb value\n");
+ for (fpreg = 0; fpreg < 8; fpreg++)
+ {
+ long double val;
-int
-redir_cmdline_parse (const char *args, cmdline_t *ptr)
-{
- return -1;
-}
+ printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
-int
-redir_to_child (cmdline_t *ptr)
-{
- return 1;
-}
+ switch ((ep->tag >> (fpreg * 2)) & 3)
+ {
+ case 0:
+ printf_unfiltered ("valid ");
+ break;
+ case 1:
+ printf_unfiltered ("zero ");
+ break;
+ case 2:
+ printf_unfiltered ("trap ");
+ break;
+ case 3:
+ printf_unfiltered ("empty ");
+ break;
+ }
+ for (i = 0; i < 8; i++)
+ printf_unfiltered ("%02x", ep->regs[fpreg][i]);
-int
-redir_to_debugger (cmdline_t *ptr)
-{
- return 1;
+ REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM + fpreg, builtin_type_long_double,
+ &ep->regs[fpreg], &val);
+
+ printf_unfiltered (" %LG\n", val);
+ }
}
-int
-redir_debug_init (cmdline_t *ptr)
+void
+i386_go32_float_info (void)
{
- return 0;
+ print_387_status (0, (struct env387 *) &npx);
}
-#endif /* __DJGPP_MINOR < 3 */
-typedef enum { wp_insert, wp_remove, wp_count } wp_op;
-
-/* This holds the current reference counts for each debug register. */
-static int dr_ref_count[4];
-
-#define SOME_PID 42
-
-static int prog_has_started = 0;
-static void go32_open (char *name, int from_tty);
-static void go32_close (int quitting);
-static void go32_attach (char *args, int from_tty);
-static void go32_detach (char *args, int from_tty);
-static void go32_resume (ptid_t ptid, int step,
- enum target_signal siggnal);
-static ptid_t go32_wait (ptid_t ptid,
- struct target_waitstatus *status);
-static void go32_fetch_registers (struct regcache *, int regno);
-static void store_register (const struct regcache *, int regno);
-static void go32_store_registers (struct regcache *, int regno);
-static void go32_prepare_to_store (struct regcache *);
-static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
- int write,
- struct mem_attrib *attrib,
- struct target_ops *target);
-static void go32_files_info (struct target_ops *target);
-static void go32_stop (ptid_t);
-static void go32_kill_inferior (void);
-static void go32_create_inferior (char *exec_file, char *args, char **env, int from_tty);
-static void go32_mourn_inferior (void);
-static int go32_can_run (void);
-
-static struct target_ops go32_ops;
-static void go32_terminal_init (void);
-static void go32_terminal_inferior (void);
-static void go32_terminal_ours (void);
-
-#define r_ofs(x) (offsetof(TSS,x))
+#define r_ofs(x) ((int)(&(((TSS *)0)->x)))
static struct
{
- size_t tss_ofs;
- size_t size;
+ int tss_ofs;
+ int size;
}
regno_mapping[] =
{
- {r_ofs (tss_eax), 4}, /* normal registers, from a_tss */
- {r_ofs (tss_ecx), 4},
- {r_ofs (tss_edx), 4},
- {r_ofs (tss_ebx), 4},
- {r_ofs (tss_esp), 4},
- {r_ofs (tss_ebp), 4},
- {r_ofs (tss_esi), 4},
- {r_ofs (tss_edi), 4},
- {r_ofs (tss_eip), 4},
- {r_ofs (tss_eflags), 4},
- {r_ofs (tss_cs), 2},
- {r_ofs (tss_ss), 2},
- {r_ofs (tss_ds), 2},
- {r_ofs (tss_es), 2},
- {r_ofs (tss_fs), 2},
- {r_ofs (tss_gs), 2},
- {0, 10}, /* 8 FP registers, from npx.reg[] */
- {1, 10},
- {2, 10},
- {3, 10},
- {4, 10},
- {5, 10},
- {6, 10},
- {7, 10},
- /* The order of the next 7 registers must be consistent
- with their numbering in config/i386/tm-i386.h, which see. */
- {0, 2}, /* control word, from npx */
- {4, 2}, /* status word, from npx */
- {8, 2}, /* tag word, from npx */
- {16, 2}, /* last FP exception CS from npx */
- {12, 4}, /* last FP exception EIP from npx */
- {24, 2}, /* last FP exception operand selector from npx */
- {20, 4}, /* last FP exception operand offset from npx */
- {18, 2} /* last FP opcode from npx */
+ r_ofs (tss_eax), 4,
+ r_ofs (tss_ecx), 4,
+ r_ofs (tss_edx), 4,
+ r_ofs (tss_ebx), 4,
+ r_ofs (tss_esp), 4,
+ r_ofs (tss_ebp), 4,
+ r_ofs (tss_esi), 4,
+ r_ofs (tss_edi), 4,
+ r_ofs (tss_eip), 4,
+ r_ofs (tss_eflags), 4,
+ r_ofs (tss_cs), 2,
+ r_ofs (tss_ss), 2,
+ r_ofs (tss_ds), 2,
+ r_ofs (tss_es), 2,
+ r_ofs (tss_fs), 2,
+ r_ofs (tss_gs), 2,
+ 0, 10,
+ 1, 10,
+ 2, 10,
+ 3, 10,
+ 4, 10,
+ 5, 10,
+ 6, 10,
+ 7, 10,
+ 0, 2,
+ 4, 2,
+ 8, 2,
+ 12, 4,
+ 16, 2,
+ 20, 4,
+ 24, 2
};
static struct
{
int go32_sig;
- enum target_signal gdb_sig;
+ int gdb_sig;
}
sig_map[] =
{
- {0, TARGET_SIGNAL_FPE},
- {1, TARGET_SIGNAL_TRAP},
- /* Exception 2 is triggered by the NMI. DJGPP handles it as SIGILL,
- but I think SIGBUS is better, since the NMI is usually activated
- as a result of a memory parity check failure. */
- {2, TARGET_SIGNAL_BUS},
- {3, TARGET_SIGNAL_TRAP},
- {4, TARGET_SIGNAL_FPE},
- {5, TARGET_SIGNAL_SEGV},
- {6, TARGET_SIGNAL_ILL},
- {7, TARGET_SIGNAL_EMT}, /* no-coprocessor exception */
- {8, TARGET_SIGNAL_SEGV},
- {9, TARGET_SIGNAL_SEGV},
- {10, TARGET_SIGNAL_BUS},
- {11, TARGET_SIGNAL_SEGV},
- {12, TARGET_SIGNAL_SEGV},
- {13, TARGET_SIGNAL_SEGV},
- {14, TARGET_SIGNAL_SEGV},
- {16, TARGET_SIGNAL_FPE},
- {17, TARGET_SIGNAL_BUS},
- {31, TARGET_SIGNAL_ILL},
- {0x1b, TARGET_SIGNAL_INT},
- {0x75, TARGET_SIGNAL_FPE},
- {0x78, TARGET_SIGNAL_ALRM},
- {0x79, TARGET_SIGNAL_INT},
- {0x7a, TARGET_SIGNAL_QUIT},
- {-1, TARGET_SIGNAL_LAST}
-};
-
-static struct {
- enum target_signal gdb_sig;
- int djgpp_excepno;
-} excepn_map[] = {
- {TARGET_SIGNAL_0, -1},
- {TARGET_SIGNAL_ILL, 6}, /* Invalid Opcode */
- {TARGET_SIGNAL_EMT, 7}, /* triggers SIGNOFP */
- {TARGET_SIGNAL_SEGV, 13}, /* GPF */
- {TARGET_SIGNAL_BUS, 17}, /* Alignment Check */
- /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
- details. */
- {TARGET_SIGNAL_TERM, 0x1b}, /* triggers Ctrl-Break type of SIGINT */
- {TARGET_SIGNAL_FPE, 0x75},
- {TARGET_SIGNAL_INT, 0x79},
- {TARGET_SIGNAL_QUIT, 0x7a},
- {TARGET_SIGNAL_ALRM, 0x78}, /* triggers SIGTIMR */
- {TARGET_SIGNAL_PROF, 0x78},
- {TARGET_SIGNAL_LAST, -1}
+ 0, TARGET_SIGNAL_FPE,
+ 1, TARGET_SIGNAL_TRAP,
+ 2, TARGET_SIGNAL_UNKNOWN,
+ 3, TARGET_SIGNAL_TRAP,
+ 4, TARGET_SIGNAL_FPE,
+ 5, TARGET_SIGNAL_SEGV,
+ 6, TARGET_SIGNAL_ILL,
+ 7, TARGET_SIGNAL_FPE,
+ 8, TARGET_SIGNAL_SEGV,
+ 9, TARGET_SIGNAL_SEGV,
+ 10, TARGET_SIGNAL_BUS,
+ 11, TARGET_SIGNAL_SEGV,
+ 12, TARGET_SIGNAL_SEGV,
+ 13, TARGET_SIGNAL_ABRT,
+ 14, TARGET_SIGNAL_SEGV,
+ 16, TARGET_SIGNAL_FPE,
+ 31, TARGET_SIGNAL_ILL,
+ 0x75, TARGET_SIGNAL_FPE,
+ 0x79, TARGET_SIGNAL_INT,
+ 0x1b, TARGET_SIGNAL_INT,
+ -1, -1
};
static void
go32_open (char *name, int from_tty)
{
- printf_unfiltered ("Done. Use the \"run\" command to run the program.\n");
+ printf_unfiltered ("Use the `run' command to run go32 programs\n");
}
static void
@@ -307,9 +219,7 @@ go32_close (int quitting)
static void
go32_attach (char *args, int from_tty)
{
- error (_("\
-You cannot attach to a running program on this platform.\n\
-Use the `run' command to run DJGPP programs."));
+ printf_unfiltered ("Use the `run' command to run go32 programs\n");
}
static void
@@ -318,122 +228,24 @@ go32_detach (char *args, int from_tty)
}
static int resume_is_step;
-static int resume_signal = -1;
static void
-go32_resume (ptid_t ptid, int step, enum target_signal siggnal)
-{
- int i;
-
- resume_is_step = step;
-
- if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP)
+go32_resume (int pid, int step, enum target_signal siggnal)
{
- for (i = 0, resume_signal = -1;
- excepn_map[i].gdb_sig != TARGET_SIGNAL_LAST; i++)
- if (excepn_map[i].gdb_sig == siggnal)
- {
- resume_signal = excepn_map[i].djgpp_excepno;
- break;
- }
- if (resume_signal == -1)
- printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
- target_signal_to_name (siggnal));
+ resume_is_step = step;
}
-}
-
-static char child_cwd[FILENAME_MAX];
-static ptid_t
-go32_wait (ptid_t ptid, struct target_waitstatus *status)
+static int
+go32_wait (int pid, struct target_waitstatus *status)
{
int i;
- unsigned char saved_opcode;
- unsigned long INT3_addr = 0;
- int stepping_over_INT = 0;
- a_tss.tss_eflags &= 0xfeff; /* reset the single-step flag (TF) */
if (resume_is_step)
- {
- /* If the next instruction is INT xx or INTO, we need to handle
- them specially. Intel manuals say that these instructions
- reset the single-step flag (a.k.a. TF). However, it seems
- that, at least in the DPMI environment, and at least when
- stepping over the DPMI interrupt 31h, the problem is having
- TF set at all when INT 31h is executed: the debuggee either
- crashes (and takes the system with it) or is killed by a
- SIGTRAP.
-
- So we need to emulate single-step mode: we put an INT3 opcode
- right after the INT xx instruction, let the debuggee run
- until it hits INT3 and stops, then restore the original
- instruction which we overwrote with the INT3 opcode, and back
- up the debuggee's EIP to that instruction. */
- read_child (a_tss.tss_eip, &saved_opcode, 1);
- if (saved_opcode == 0xCD || saved_opcode == 0xCE)
- {
- unsigned char INT3_opcode = 0xCC;
-
- INT3_addr
- = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1;
- stepping_over_INT = 1;
- read_child (INT3_addr, &saved_opcode, 1);
- write_child (INT3_addr, &INT3_opcode, 1);
- }
- else
- a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
- }
-
- /* The special value FFFFh in tss_trap indicates to run_child that
- tss_irqn holds a signal to be delivered to the debuggee. */
- if (resume_signal <= -1)
- {
- a_tss.tss_trap = 0;
- a_tss.tss_irqn = 0xff;
- }
+ a_tss.tss_eflags |= 0x0100;
else
- {
- a_tss.tss_trap = 0xffff; /* run_child looks for this */
- a_tss.tss_irqn = resume_signal;
- }
+ a_tss.tss_eflags &= 0xfeff;
- /* The child might change working directory behind our back. The
- GDB users won't like the side effects of that when they work with
- relative file names, and GDB might be confused by its current
- directory not being in sync with the truth. So we always make a
- point of changing back to where GDB thinks is its cwd, when we
- return control to the debugger, but restore child's cwd before we
- run it. */
- /* Initialize child_cwd, before the first call to run_child and not
- in the initialization, so the child get also the changed directory
- set with the gdb-command "cd ..." */
- if (!*child_cwd)
- /* Initialize child's cwd with the current one. */
- getcwd (child_cwd, sizeof (child_cwd));
-
- chdir (child_cwd);
-
-#if __DJGPP_MINOR__ < 3
- load_npx ();
-#endif
run_child ();
-#if __DJGPP_MINOR__ < 3
- save_npx ();
-#endif
-
- /* Did we step over an INT xx instruction? */
- if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
- {
- /* Restore the original opcode. */
- a_tss.tss_eip--; /* EIP points *after* the INT3 instruction */
- write_child (a_tss.tss_eip, &saved_opcode, 1);
- /* Simulate a TRAP exception. */
- a_tss.tss_irqn = 1;
- a_tss.tss_eflags |= 0x0100;
- }
-
- getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
- chdir (current_directory);
if (a_tss.tss_irqn == 0x21)
{
@@ -448,84 +260,91 @@ go32_wait (ptid_t ptid, struct target_waitstatus *status)
{
if (a_tss.tss_irqn == sig_map[i].go32_sig)
{
-#if __DJGPP_MINOR__ < 3
if ((status->value.sig = sig_map[i].gdb_sig) !=
TARGET_SIGNAL_TRAP)
status->kind = TARGET_WAITKIND_SIGNALLED;
-#else
- status->value.sig = sig_map[i].gdb_sig;
-#endif
break;
}
}
}
- return pid_to_ptid (SOME_PID);
+ return SOME_PID;
}
static void
-fetch_register (struct regcache *regcache, int regno)
+go32_fetch_registers (int regno)
{
- if (regno < gdbarch_fp0_regnum (get_regcache_arch (regcache)))
- regcache_raw_supply (regcache, regno,
- (char *) &a_tss + regno_mapping[regno].tss_ofs);
- else if (i386_fp_regnum_p (regno) || i386_fpc_regnum_p (regno))
- i387_supply_fsave (regcache, regno, &npx);
- else
- internal_error (__FILE__, __LINE__,
- _("Invalid register no. %d in fetch_register."), regno);
-}
+ /*JHW*/
+ int end_reg = regno + 1; /* just one reg initially */
-static void
-go32_fetch_registers (struct regcache *regcache, int regno)
-{
- if (regno >= 0)
- fetch_register (regcache, regno);
- else
+ if (regno < 0) /* do the all registers */
{
- for (regno = 0;
- regno < gdbarch_fp0_regnum (get_regcache_arch (regcache));
- regno++)
- fetch_register (regcache, regno);
- i387_supply_fsave (regcache, -1, &npx);
+ regno = 0; /* start at first register */
+ /* # regs in table */
+ end_reg = sizeof (regno_mapping) / sizeof (regno_mapping[0]);
+ }
+
+ for (; regno < end_reg; regno++)
+ {
+ if (regno < 16)
+ supply_register (regno,
+ (char *) &a_tss + regno_mapping[regno].tss_ofs);
+ else if (regno < 24)
+ supply_register (regno,
+ (char *) &npx.reg[regno_mapping[regno].tss_ofs]);
+ else if (regno < 31)
+ supply_register (regno,
+ (char *) &npx.reg + regno_mapping[regno].tss_ofs);
+ else
+ {
+ printf_unfiltered ("Invalid register in go32_fetch_register(%d)",
+ regno);
+ exit (1);
+ }
}
}
static void
-store_register (const struct regcache *regcache, int regno)
+store_register (int regno)
{
- if (regno < gdbarch_fp0_regnum (get_regcache_arch (regcache)))
- regcache_raw_collect (regcache, regno,
- (char *) &a_tss + regno_mapping[regno].tss_ofs);
- else if (i386_fp_regnum_p (regno) || i386_fpc_regnum_p (regno))
- i387_collect_fsave (regcache, regno, &npx);
+ void *rp;
+ void *v = (void *) &registers[REGISTER_BYTE (regno)];
+
+ if (regno < 16)
+ rp = (char *) &a_tss + regno_mapping[regno].tss_ofs;
+ else if (regno < 24)
+ rp = (char *) &npx.reg[regno_mapping[regno].tss_ofs];
+ else if (regno > 31)
+ rp = (char *) &npx + regno_mapping[regno].tss_ofs;
else
- internal_error (__FILE__, __LINE__,
- _("Invalid register no. %d in store_register."), regno);
+ {
+ printf_unfiltered ("Invalid register in store_register(%d)", regno);
+ exit (1);
+ }
+ memcpy (rp, v, regno_mapping[regno].size);
}
static void
-go32_store_registers (struct regcache *regcache, int regno)
+go32_store_registers (int regno)
{
- unsigned r;
+ int r;
if (regno >= 0)
- store_register (regcache, regno);
+ store_register (regno);
else
{
- for (r = 0; r < gdbarch_fp0_regnum (get_regcache_arch (regcache)); r++)
- store_register (regcache, r);
- i387_collect_fsave (regcache, -1, &npx);
+ for (r = 0; r < sizeof (regno_mapping) / sizeof (regno_mapping[0]); r++)
+ store_register (r);
}
}
static void
-go32_prepare_to_store (struct regcache *regcache)
+go32_prepare_to_store (void)
{
}
static int
go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
- struct mem_attrib *attrib, struct target_ops *target)
+ struct target_ops *target)
{
if (write)
{
@@ -551,92 +370,44 @@ go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
}
}
-static cmdline_t child_cmd; /* parsed child's command line kept here */
-
static void
go32_files_info (struct target_ops *target)
{
- printf_unfiltered ("You are running a DJGPP V2 program.\n");
+ printf_unfiltered ("You are running a DJGPP V2 program\n");
}
static void
-go32_stop (ptid_t ptid)
+go32_stop (void)
{
normal_stop ();
cleanup_client ();
- inferior_ptid = null_ptid;
+ inferior_pid = 0;
prog_has_started = 0;
}
static void
go32_kill_inferior (void)
{
- redir_cmdline_delete (&child_cmd);
- resume_signal = -1;
- resume_is_step = 0;
+ go32_stop ();
unpush_target (&go32_ops);
}
static void
-go32_create_inferior (char *exec_file, char *args, char **env, int from_tty)
+go32_create_inferior (char *exec_file, char *args, char **env)
{
- extern char **environ;
jmp_buf start_state;
char *cmdline;
char **env_save = environ;
- size_t cmdlen;
-
- /* 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);
if (prog_has_started)
{
- go32_stop (inferior_ptid);
go32_kill_inferior ();
}
- resume_signal = -1;
- resume_is_step = 0;
-
- /* Initialize child's cwd as empty to be initialized when starting
- the child. */
- *child_cwd = 0;
-
- /* Init command line storage. */
- if (redir_debug_init (&child_cmd) == -1)
- internal_error (__FILE__, __LINE__,
- _("Cannot allocate redirection storage: not enough memory.\n"));
-
- /* Parse the command line and create redirections. */
- if (strpbrk (args, "<>"))
- {
- if (redir_cmdline_parse (args, &child_cmd) == 0)
- args = child_cmd.command;
- else
- error (_("Syntax error in command line."));
- }
- else
- child_cmd.command = xstrdup (args);
-
- cmdlen = strlen (args);
- /* v2loadimage passes command lines via DOS memory, so it cannot
- possibly handle commands longer than 1MB. */
- if (cmdlen > 1024*1024)
- error (_("Command line too long."));
- cmdline = xmalloc (cmdlen + 4);
+ cmdline = (char *) alloca (strlen (args) + 4);
+ cmdline[0] = strlen (args);
strcpy (cmdline + 1, args);
- /* If the command-line length fits into DOS 126-char limits, use the
- DOS command tail format; otherwise, tell v2loadimage to pass it
- through a buffer in conventional memory. */
- if (cmdlen < 127)
- {
- cmdline[0] = strlen (args);
- cmdline[cmdlen + 1] = 13;
- }
- else
- cmdline[0] = 0xff; /* signal v2loadimage it's a long command */
+ cmdline[strlen (args) + 1] = 13;
environ = env;
@@ -647,31 +418,19 @@ go32_create_inferior (char *exec_file, char *args, char **env, int from_tty)
exit (1);
}
environ = env_save;
- xfree (cmdline);
edi_init (start_state);
-#if __DJGPP_MINOR__ < 3
- save_npx ();
-#endif
- inferior_ptid = pid_to_ptid (SOME_PID);
+ inferior_pid = SOME_PID;
push_target (&go32_ops);
clear_proceed_status ();
insert_breakpoints ();
- prog_has_started = 1;
+ proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
}
static void
go32_mourn_inferior (void)
{
- /* We need to make sure all the breakpoint enable bits in the DR7
- register are reset when the inferior exits. Otherwise, if they
- rerun the inferior, the uncleared bits may cause random SIGTRAPs,
- failure to set more watchpoints, and other calamities. It would
- be nice if GDB itself would take care to remove all breakpoints
- at all times, but it doesn't, probably under an assumption that
- the OS cleans up when the debuggee exits. */
- i386_cleanup_dregs ();
go32_kill_inferior ();
generic_mourn_inferior ();
}
@@ -682,1226 +441,309 @@ go32_can_run (void)
return 1;
}
-/* Hardware watchpoint support. */
-
-#define D_REGS edi.dr
-#define CONTROL D_REGS[7]
-#define STATUS D_REGS[6]
-
-/* Pass the address ADDR to the inferior in the I'th debug register.
- Here we just store the address in D_REGS, the watchpoint will be
- actually set up when go32_wait runs the debuggee. */
-void
-go32_set_dr (int i, CORE_ADDR addr)
-{
- if (i < 0 || i > 3)
- internal_error (__FILE__, __LINE__,
- _("Invalid register %d in go32_set_dr.\n"), i);
- D_REGS[i] = addr;
-}
-
-/* Pass the value VAL to the inferior in the DR7 debug control
- register. Here we just store the address in D_REGS, the watchpoint
- will be actually set up when go32_wait runs the debuggee. */
-void
-go32_set_dr7 (unsigned val)
-{
- CONTROL = val;
-}
-
-/* Get the value of the DR6 debug status register from the inferior.
- Here we just return the value stored in D_REGS, as we've got it
- from the last go32_wait call. */
-unsigned
-go32_get_dr6 (void)
-{
- return STATUS;
-}
-
-/* Put the device open on handle FD into either raw or cooked
- mode, return 1 if it was in raw mode, zero otherwise. */
-
-static int
-device_mode (int fd, int raw_p)
-{
- int oldmode, newmode;
- __dpmi_regs regs;
-
- regs.x.ax = 0x4400;
- regs.x.bx = fd;
- __dpmi_int (0x21, &regs);
- if (regs.x.flags & 1)
- return -1;
- newmode = oldmode = regs.x.dx;
-
- if (raw_p)
- newmode |= 0x20;
- else
- newmode &= ~0x20;
-
- if (oldmode & 0x80) /* Only for character dev */
- {
- regs.x.ax = 0x4401;
- regs.x.bx = fd;
- regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
- __dpmi_int (0x21, &regs);
- if (regs.x.flags & 1)
- return -1;
- }
- return (oldmode & 0x20) == 0x20;
-}
-
-
-static int inf_mode_valid = 0;
-static int inf_terminal_mode;
-
-/* This semaphore is needed because, amazingly enough, GDB calls
- target.to_terminal_ours more than once after the inferior stops.
- But we need the information from the first call only, since the
- second call will always see GDB's own cooked terminal. */
-static int terminal_is_ours = 1;
-
-static void
-go32_terminal_init (void)
-{
- inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
- terminal_is_ours = 1;
-}
-
static void
-go32_terminal_info (char *args, int from_tty)
+ignore (void)
{
- printf_unfiltered ("Inferior's terminal is in %s mode.\n",
- !inf_mode_valid
- ? "default" : inf_terminal_mode ? "raw" : "cooked");
-
-#if __DJGPP_MINOR__ > 2
- if (child_cmd.redirection)
- {
- int i;
-
- for (i = 0; i < DBG_HANDLES; i++)
- {
- if (child_cmd.redirection[i]->file_name)
- printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
- i, child_cmd.redirection[i]->file_name);
- else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
- printf_unfiltered
- ("\tFile handle %d appears to be closed by inferior.\n", i);
- /* Mask off the raw/cooked bit when comparing device info words. */
- else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
- != (_get_dev_info (i) & 0xdf))
- printf_unfiltered
- ("\tFile handle %d appears to be redirected by inferior.\n", i);
- }
- }
-#endif
}
static void
-go32_terminal_inferior (void)
+ignore2 (char *a, int b)
{
- /* Redirect standard handles as child wants them. */
- errno = 0;
- if (redir_to_child (&child_cmd) == -1)
- {
- redir_to_debugger (&child_cmd);
- error (_("Cannot redirect standard handles for program: %s."),
- safe_strerror (errno));
- }
- /* set the console device of the inferior to whatever mode
- (raw or cooked) we found it last time */
- if (terminal_is_ours)
- {
- if (inf_mode_valid)
- device_mode (0, inf_terminal_mode);
- terminal_is_ours = 0;
- }
}
-static void
-go32_terminal_ours (void)
-{
- /* Switch to cooked mode on the gdb terminal and save the inferior
- terminal mode to be restored when it is resumed */
- if (!terminal_is_ours)
- {
- inf_terminal_mode = device_mode (0, 0);
- if (inf_terminal_mode != -1)
- inf_mode_valid = 1;
- else
- /* If device_mode returned -1, we don't know what happens with
- handle 0 anymore, so make the info invalid. */
- inf_mode_valid = 0;
- terminal_is_ours = 1;
-
- /* Restore debugger's standard handles. */
- errno = 0;
- if (redir_to_debugger (&child_cmd) == -1)
- {
- redir_to_child (&child_cmd);
- error (_("Cannot redirect standard handles for debugger: %s."),
- safe_strerror (errno));
- }
- }
-}
-
-static void
-init_go32_ops (void)
-{
- go32_ops.to_shortname = "djgpp";
- go32_ops.to_longname = "djgpp target process";
- go32_ops.to_doc =
- "Program loaded by djgpp, when gdb is used as an external debugger";
- go32_ops.to_open = go32_open;
- go32_ops.to_close = go32_close;
- go32_ops.to_attach = go32_attach;
- go32_ops.to_detach = go32_detach;
- go32_ops.to_resume = go32_resume;
- go32_ops.to_wait = go32_wait;
- go32_ops.to_fetch_registers = go32_fetch_registers;
- go32_ops.to_store_registers = go32_store_registers;
- go32_ops.to_prepare_to_store = go32_prepare_to_store;
- go32_ops.deprecated_xfer_memory = go32_xfer_memory;
- go32_ops.to_files_info = go32_files_info;
- go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
- go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
- go32_ops.to_terminal_init = go32_terminal_init;
- go32_ops.to_terminal_inferior = go32_terminal_inferior;
- go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
- go32_ops.to_terminal_ours = go32_terminal_ours;
- go32_ops.to_terminal_info = go32_terminal_info;
- go32_ops.to_kill = go32_kill_inferior;
- go32_ops.to_create_inferior = go32_create_inferior;
- go32_ops.to_mourn_inferior = go32_mourn_inferior;
- go32_ops.to_can_run = go32_can_run;
- go32_ops.to_stop = go32_stop;
- go32_ops.to_stratum = process_stratum;
- go32_ops.to_has_all_memory = 1;
- go32_ops.to_has_memory = 1;
- go32_ops.to_has_stack = 1;
- go32_ops.to_has_registers = 1;
- go32_ops.to_has_execution = 1;
- go32_ops.to_magic = OPS_MAGIC;
+/* Hardware watchpoint support. */
- /* Initialize child's cwd as empty to be initialized when starting
- the child. */
- *child_cwd = 0;
+#define DR_STATUS 6
+#define DR_CONTROL 7
+#define DR_ENABLE_SIZE 2
+#define DR_LOCAL_ENABLE_SHIFT 0
+#define DR_GLOBAL_ENABLE_SHIFT 1
+#define DR_LOCAL_SLOWDOWN 0x100
+#define DR_GLOBAL_SLOWDOWN 0x200
+#define DR_CONTROL_SHIFT 16
+#define DR_CONTROL_SIZE 4
+#define DR_RW_READ 0x3
+#define DR_RW_WRITE 0x1
+#define DR_CONTROL_MASK 0xf
+#define DR_ENABLE_MASK 0x3
+#define DR_LEN_1 0x0
+#define DR_LEN_2 0x4
+#define DR_LEN_4 0xc
- /* Initialize child's command line storage. */
- if (redir_debug_init (&child_cmd) == -1)
- internal_error (__FILE__, __LINE__,
- _("Cannot allocate redirection storage: not enough memory.\n"));
+#define D_REGS edi.dr
+#define CONTROL D_REGS[DR_CONTROL]
+#define STATUS D_REGS[DR_STATUS]
+
+#define IS_REG_FREE(index) \
+ (!(CONTROL & (3 << (DR_ENABLE_SIZE * index))))
+
+#define LOCAL_ENABLE_REG(index) \
+ (CONTROL |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * index)))
+
+#define GLOBAL_ENABLE_REG(index) \
+ (CONTROL |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * index)))
+
+#define DISABLE_REG(index) \
+ (CONTROL &= ~(3 << (DR_ENABLE_SIZE * index)))
+
+#define SET_LOCAL_EXACT() \
+ (CONTROL |= DR_LOCAL_SLOWDOWN)
+
+#define SET_GLOBAL_EXACT() \
+ (CONTROL |= DR_GLOBAL_SLOWDOWN)
+
+#define SET_BREAK(index,address) \
+ do {\
+ CONTROL &= ~(DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index));\
+ D_REGS[index] = address;\
+ } while(0)
+
+#define SET_WATCH(index,address,rw,len) \
+ do {\
+ SET_BREAK(index,address);\
+ CONTROL |= (len | rw) << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index);\
+ } while (0)
+
+#define WATCH_HIT(index) \
+ (\
+ (STATUS & (1 << index)) && \
+ (CONTROL & (DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index)))\
+ )
+
+#if 0 /* use debugging macro */
+#define SHOW_DR(text) \
+do { \
+ fprintf(stderr,"%08x %08x ",edi.dr[7],edi.dr[6]); \
+ fprintf(stderr,"%08x %08x ",edi.dr[0],edi.dr[1]); \
+ fprintf(stderr,"%08x %08x ",edi.dr[2],edi.dr[3]); \
+ fprintf(stderr,"(%s)\n",#text); \
+} while (0)
+#else
+#define SHOW_DR(text) do {} while (0)
+#endif
- /* We are always processing GCC-compiled programs. */
- processing_gcc_compilation = 2;
+static int go32_insert_aligned_watchpoint (int pid, CORE_ADDR waddr,
+ CORE_ADDR addr, int len, int rw);
- /* Override the default name of the GDB init file. */
- strcpy (gdbinit, "gdb.ini");
-}
+static int go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr,
+ CORE_ADDR addr, int len, int rw);
-unsigned short windows_major, windows_minor;
+/* Insert a watchpoint. */
-/* Compute the version Windows reports via Int 2Fh/AX=1600h. */
-static void
-go32_get_windows_version(void)
+int
+go32_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
{
- __dpmi_regs r;
+ int ret = go32_insert_aligned_watchpoint (pid, addr, addr, len, rw);
- r.x.ax = 0x1600;
- __dpmi_int(0x2f, &r);
- if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff
- && (r.h.al > 3 || r.h.ah > 0))
- {
- windows_major = r.h.al;
- windows_minor = r.h.ah;
- }
- else
- windows_major = 0xff; /* meaning no Windows */
+ SHOW_DR (insert_watch);
+ return ret;
}
-/* A subroutine of go32_sysinfo to display memory info. */
-static void
-print_mem (unsigned long datum, const char *header, int in_pages_p)
+static int
+go32_insert_aligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr,
+ int len, int rw)
{
- if (datum != 0xffffffffUL)
- {
- if (in_pages_p)
- datum <<= 12;
- puts_filtered (header);
- if (datum > 1024)
- {
- printf_filtered ("%lu KB", datum >> 10);
- if (datum > 1024 * 1024)
- printf_filtered (" (%lu MB)", datum >> 20);
- }
- else
- printf_filtered ("%lu Bytes", datum);
- puts_filtered ("\n");
- }
-}
+ int i;
+ int read_write_bits, len_bits;
-/* Display assorted information about the underlying OS. */
-static void
-go32_sysinfo (char *arg, int from_tty)
-{
- struct utsname u;
- char cpuid_vendor[13];
- unsigned cpuid_max = 0, cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
- unsigned true_dos_version = _get_dos_version (1);
- unsigned advertized_dos_version = ((unsigned int)_osmajor << 8) | _osminor;
- int dpmi_flags;
- char dpmi_vendor_info[129];
- int dpmi_vendor_available =
- __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info);
- __dpmi_version_ret dpmi_version_data;
- long eflags;
- __dpmi_free_mem_info mem_info;
- __dpmi_regs regs;
-
- cpuid_vendor[0] = '\0';
- if (uname (&u))
- strcpy (u.machine, "Unknown x86");
- else if (u.machine[0] == 'i' && u.machine[1] > 4)
+ /* Look for a free debug register. */
+ for (i = 0; i <= 3; i++)
{
- /* CPUID with EAX = 0 returns the Vendor ID. */
- __asm__ __volatile__ ("xorl %%ebx, %%ebx;"
- "xorl %%ecx, %%ecx;"
- "xorl %%edx, %%edx;"
- "movl $0, %%eax;"
- "cpuid;"
- "movl %%ebx, %0;"
- "movl %%edx, %1;"
- "movl %%ecx, %2;"
- "movl %%eax, %3;"
- : "=m" (cpuid_vendor[0]),
- "=m" (cpuid_vendor[4]),
- "=m" (cpuid_vendor[8]),
- "=m" (cpuid_max)
- :
- : "%eax", "%ebx", "%ecx", "%edx");
- cpuid_vendor[12] = '\0';
+ if (IS_REG_FREE (i))
+ break;
}
- printf_filtered ("CPU Type.......................%s", u.machine);
- if (cpuid_vendor[0])
- printf_filtered (" (%s)", cpuid_vendor);
- puts_filtered ("\n");
+ /* No more debug registers! */
+ if (i > 3)
+ return -1;
- /* CPUID with EAX = 1 returns processor signature and features. */
- if (cpuid_max >= 1)
- {
- static char *brand_name[] = {
- "",
- " Celeron",
- " III",
- " III Xeon",
- "", "", "", "",
- " 4"
- };
- char cpu_string[80];
- char cpu_brand[20];
- unsigned brand_idx;
- int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
- int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
- unsigned cpu_family, cpu_model;
-
- __asm__ __volatile__ ("movl $1, %%eax;"
- "cpuid;"
- : "=a" (cpuid_eax),
- "=b" (cpuid_ebx),
- "=d" (cpuid_edx)
- :
- : "%ecx");
- brand_idx = cpuid_ebx & 0xff;
- cpu_family = (cpuid_eax >> 8) & 0xf;
- cpu_model = (cpuid_eax >> 4) & 0xf;
- cpu_brand[0] = '\0';
- if (intel_p)
- {
- if (brand_idx > 0
- && brand_idx < sizeof(brand_name)/sizeof(brand_name[0])
- && *brand_name[brand_idx])
- strcpy (cpu_brand, brand_name[brand_idx]);
- else if (cpu_family == 5)
- {
- if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4)
- strcpy (cpu_brand, " MMX");
- else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1)
- strcpy (cpu_brand, " OverDrive");
- else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2)
- strcpy (cpu_brand, " Dual");
- }
- else if (cpu_family == 6 && cpu_model < 8)
- {
- switch (cpu_model)
- {
- case 1:
- strcpy (cpu_brand, " Pro");
- break;
- case 3:
- strcpy (cpu_brand, " II");
- break;
- case 5:
- strcpy (cpu_brand, " II Xeon");
- break;
- case 6:
- strcpy (cpu_brand, " Celeron");
- break;
- case 7:
- strcpy (cpu_brand, " III");
- break;
- }
- }
- }
- else if (amd_p)
- {
- switch (cpu_family)
- {
- case 4:
- strcpy (cpu_brand, "486/5x86");
- break;
- case 5:
- switch (cpu_model)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- strcpy (cpu_brand, "-K5");
- break;
- case 6:
- case 7:
- strcpy (cpu_brand, "-K6");
- break;
- case 8:
- strcpy (cpu_brand, "-K6-2");
- break;
- case 9:
- strcpy (cpu_brand, "-K6-III");
- break;
- }
- break;
- case 6:
- switch (cpu_model)
- {
- case 1:
- case 2:
- case 4:
- strcpy (cpu_brand, " Athlon");
- break;
- case 3:
- strcpy (cpu_brand, " Duron");
- break;
- }
- break;
- }
- }
- sprintf (cpu_string, "%s%s Model %d Stepping %d",
- intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
- cpu_brand, cpu_model, cpuid_eax & 0xf);
- printfi_filtered (31, "%s\n", cpu_string);
- if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
- || ((cpuid_edx & 1) == 0)
- || (amd_p && (cpuid_edx & (3 << 30)) != 0))
- {
- puts_filtered ("CPU Features...................");
- /* We only list features which might be useful in the DPMI
- environment. */
- if ((cpuid_edx & 1) == 0)
- puts_filtered ("No FPU "); /* it's unusual to not have an FPU */
- if ((cpuid_edx & (1 << 1)) != 0)
- puts_filtered ("VME ");
- if ((cpuid_edx & (1 << 2)) != 0)
- puts_filtered ("DE ");
- if ((cpuid_edx & (1 << 4)) != 0)
- puts_filtered ("TSC ");
- if ((cpuid_edx & (1 << 23)) != 0)
- puts_filtered ("MMX ");
- if ((cpuid_edx & (1 << 25)) != 0)
- puts_filtered ("SSE ");
- if ((cpuid_edx & (1 << 26)) != 0)
- puts_filtered ("SSE2 ");
- if (amd_p)
- {
- if ((cpuid_edx & (1 << 31)) != 0)
- puts_filtered ("3DNow! ");
- if ((cpuid_edx & (1 << 30)) != 0)
- puts_filtered ("3DNow!Ext");
- }
- puts_filtered ("\n");
- }
- }
- puts_filtered ("\n");
- printf_filtered ("DOS Version....................%s %s.%s",
- _os_flavor, u.release, u.version);
- if (true_dos_version != advertized_dos_version)
- printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor);
- puts_filtered ("\n");
- if (!windows_major)
- go32_get_windows_version ();
- if (windows_major != 0xff)
- {
- const char *windows_flavor;
+ read_write_bits = ((rw & 1) ? DR_RW_READ : 0) | ((rw & 2) ? DR_RW_WRITE : 0);
- printf_filtered ("Windows Version................%d.%02d (Windows ",
- windows_major, windows_minor);
- switch (windows_major)
- {
- case 3:
- windows_flavor = "3.X";
- break;
- case 4:
- switch (windows_minor)
- {
- case 0:
- windows_flavor = "95, 95A, or 95B";
- break;
- case 3:
- windows_flavor = "95B OSR2.1 or 95C OSR2.5";
- break;
- case 10:
- windows_flavor = "98 or 98 SE";
- break;
- case 90:
- windows_flavor = "ME";
- break;
- default:
- windows_flavor = "9X";
- break;
- }
- break;
- default:
- windows_flavor = "??";
- break;
- }
- printf_filtered ("%s)\n", windows_flavor);
- }
- else if (true_dos_version == 0x532 && advertized_dos_version == 0x500)
- printf_filtered ("Windows Version................Windows NT or Windows 2000\n");
- puts_filtered ("\n");
- if (dpmi_vendor_available == 0)
- {
- /* The DPMI spec says the vendor string should be ASCIIZ, but
- I don't trust the vendors to follow that... */
- if (!memchr (&dpmi_vendor_info[2], 0, 126))
- dpmi_vendor_info[128] = '\0';
- printf_filtered ("DPMI Host......................%s v%d.%d (capabilities: %#x)\n",
- &dpmi_vendor_info[2],
- (unsigned)dpmi_vendor_info[0],
- (unsigned)dpmi_vendor_info[1],
- ((unsigned)dpmi_flags & 0x7f));
- }
- __dpmi_get_version (&dpmi_version_data);
- printf_filtered ("DPMI Version...................%d.%02d\n",
- dpmi_version_data.major, dpmi_version_data.minor);
- printf_filtered ("DPMI Info......................%s-bit DPMI, with%s Virtual Memory support\n",
- (dpmi_version_data.flags & 1) ? "32" : "16",
- (dpmi_version_data.flags & 4) ? "" : "out");
- printfi_filtered (31, "Interrupts reflected to %s mode\n",
- (dpmi_version_data.flags & 2) ? "V86" : "Real");
- printfi_filtered (31, "Processor type: i%d86\n",
- dpmi_version_data.cpu);
- printfi_filtered (31, "PIC base interrupt: Master: %#x Slave: %#x\n",
- dpmi_version_data.master_pic, dpmi_version_data.slave_pic);
-
- /* a_tss is only initialized when the debuggee is first run. */
- if (prog_has_started)
+ if (len == 1)
+ len_bits = DR_LEN_1;
+ else if (len == 2)
{
- __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags));
- printf_filtered ("Protection.....................Ring %d (in %s), with%s I/O protection\n",
- a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT",
- (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out");
+ if (addr % 2)
+ return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
+ len_bits = DR_LEN_2;
}
- puts_filtered ("\n");
- __dpmi_get_free_memory_information (&mem_info);
- print_mem (mem_info.total_number_of_physical_pages,
- "DPMI Total Physical Memory.....", 1);
- print_mem (mem_info.total_number_of_free_pages,
- "DPMI Free Physical Memory......", 1);
- print_mem (mem_info.size_of_paging_file_partition_in_pages,
- "DPMI Swap Space................", 1);
- print_mem (mem_info.linear_address_space_size_in_pages,
- "DPMI Total Linear Address Size.", 1);
- print_mem (mem_info.free_linear_address_space_in_pages,
- "DPMI Free Linear Address Size..", 1);
- print_mem (mem_info.largest_available_free_block_in_bytes,
- "DPMI Largest Free Memory Block.", 0);
-
- regs.h.ah = 0x48;
- regs.x.bx = 0xffff;
- __dpmi_int (0x21, &regs);
- print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
- regs.x.ax = 0x5800;
- __dpmi_int (0x21, &regs);
- if ((regs.x.flags & 1) == 0)
+ else if (len == 4)
{
- static const char *dos_hilo[] = {
- "Low", "", "", "", "High", "", "", "", "High, then Low"
- };
- static const char *dos_fit[] = {
- "First", "Best", "Last"
- };
- int hilo_idx = (regs.x.ax >> 4) & 0x0f;
- int fit_idx = regs.x.ax & 0x0f;
-
- if (hilo_idx > 8)
- hilo_idx = 0;
- if (fit_idx > 2)
- fit_idx = 0;
- printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
- dos_hilo[hilo_idx], dos_fit[fit_idx]);
- regs.x.ax = 0x5802;
- __dpmi_int (0x21, &regs);
- if ((regs.x.flags & 1) != 0)
- regs.h.al = 0;
- printfi_filtered (31, "UMBs %sin DOS memory chain\n",
- regs.h.al == 0 ? "not " : "");
+ if (addr % 4)
+ return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
+ len_bits = DR_LEN_4;
}
-}
-
-struct seg_descr {
- unsigned short limit0 __attribute__((packed));
- unsigned short base0 __attribute__((packed));
- unsigned char base1 __attribute__((packed));
- unsigned stype:5 __attribute__((packed));
- unsigned dpl:2 __attribute__((packed));
- unsigned present:1 __attribute__((packed));
- unsigned limit1:4 __attribute__((packed));
- unsigned available:1 __attribute__((packed));
- unsigned dummy:1 __attribute__((packed));
- unsigned bit32:1 __attribute__((packed));
- unsigned page_granular:1 __attribute__((packed));
- unsigned char base2 __attribute__((packed));
-};
-
-struct gate_descr {
- unsigned short offset0 __attribute__((packed));
- unsigned short selector __attribute__((packed));
- unsigned param_count:5 __attribute__((packed));
- unsigned dummy:3 __attribute__((packed));
- unsigned stype:5 __attribute__((packed));
- unsigned dpl:2 __attribute__((packed));
- unsigned present:1 __attribute__((packed));
- unsigned short offset1 __attribute__((packed));
-};
-
-/* Read LEN bytes starting at logical address ADDR, and put the result
- into DEST. Return 1 if success, zero if not. */
-static int
-read_memory_region (unsigned long addr, void *dest, size_t len)
-{
- unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds);
- int retval = 1;
-
- /* For the low memory, we can simply use _dos_ds. */
- if (addr <= dos_ds_limit - len)
- dosmemget (addr, len, dest);
else
- {
- /* For memory above 1MB we need to set up a special segment to
- be able to access that memory. */
- int sel = __dpmi_allocate_ldt_descriptors (1);
+ return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
- if (sel <= 0)
- retval = 0;
- else
- {
- int access_rights = __dpmi_get_descriptor_access_rights (sel);
- size_t segment_limit = len - 1;
-
- /* Make sure the crucial bits in the descriptor access
- rights are set correctly. Some DPMI providers might barf
- if we set the segment limit to something that is not an
- integral multiple of 4KB pages if the granularity bit is
- not set to byte-granular, even though the DPMI spec says
- it's the host's responsibility to set that bit correctly. */
- if (len > 1024 * 1024)
- {
- access_rights |= 0x8000;
- /* Page-granular segments should have the low 12 bits of
- the limit set. */
- segment_limit |= 0xfff;
- }
- else
- access_rights &= ~0x8000;
-
- if (__dpmi_set_segment_base_address (sel, addr) != -1
- && __dpmi_set_descriptor_access_rights (sel, access_rights) != -1
- && __dpmi_set_segment_limit (sel, segment_limit) != -1
- /* W2K silently fails to set the segment limit, leaving
- it at zero; this test avoids the resulting crash. */
- && __dpmi_get_segment_limit (sel) >= segment_limit)
- movedata (sel, 0, _my_ds (), (unsigned)dest, len);
- else
- retval = 0;
-
- __dpmi_free_ldt_descriptor (sel);
- }
- }
- return retval;
+ SET_WATCH (i, addr, read_write_bits, len_bits);
+ LOCAL_ENABLE_REG (i);
+ SET_LOCAL_EXACT ();
}
-/* Get a segment descriptor stored at index IDX in the descriptor
- table whose base address is TABLE_BASE. Return the descriptor
- type, or -1 if failure. */
static int
-get_descriptor (unsigned long table_base, int idx, void *descr)
-{
- unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */
-
- if (read_memory_region (addr, descr, 8))
- return (int)((struct seg_descr *)descr)->stype;
- return -1;
-}
-
-struct dtr_reg {
- unsigned short limit __attribute__((packed));
- unsigned long base __attribute__((packed));
-};
-
-/* Display a segment descriptor stored at index IDX in a descriptor
- table whose type is TYPE and whose base address is BASE_ADDR. If
- FORCE is non-zero, display even invalid descriptors. */
-static void
-display_descriptor (unsigned type, unsigned long base_addr, int idx, int force)
-{
- struct seg_descr descr;
- struct gate_descr gate;
-
- /* Get the descriptor from the table. */
- if (idx == 0 && type == 0)
- puts_filtered ("0x000: null descriptor\n");
- else if (get_descriptor (base_addr, idx, &descr) != -1)
- {
- /* For each type of descriptor table, this has a bit set if the
- corresponding type of selectors is valid in that table. */
- static unsigned allowed_descriptors[] = {
- 0xffffdafeL, /* GDT */
- 0x0000c0e0L, /* IDT */
- 0xffffdafaL /* LDT */
- };
-
- /* If the program hasn't started yet, assume the debuggee will
- have the same CPL as the debugger. */
- int cpl = prog_has_started ? (a_tss.tss_cs & 3) : _my_cs () & 3;
- unsigned long limit = (descr.limit1 << 16) | descr.limit0;
-
- if (descr.present
- && (allowed_descriptors[type] & (1 << descr.stype)) != 0)
- {
- printf_filtered ("0x%03x: ",
- type == 1
- ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
- if (descr.page_granular)
- limit = (limit << 12) | 0xfff; /* big segment: low 12 bit set */
- if (descr.stype == 1 || descr.stype == 2 || descr.stype == 3
- || descr.stype == 9 || descr.stype == 11
- || (descr.stype >= 16 && descr.stype < 32))
- printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx",
- descr.base2, descr.base1, descr.base0, limit);
-
- switch (descr.stype)
- {
- case 1:
- case 3:
- printf_filtered (" 16-bit TSS (task %sactive)",
- descr.stype == 3 ? "" : "in");
- break;
- case 2:
- puts_filtered (" LDT");
- break;
- case 4:
- memcpy (&gate, &descr, sizeof gate);
- printf_filtered ("selector=0x%04x offs=0x%04x%04x",
- gate.selector, gate.offset1, gate.offset0);
- printf_filtered (" 16-bit Call Gate (params=%d)",
- gate.param_count);
- break;
- case 5:
- printf_filtered ("TSS selector=0x%04x", descr.base0);
- printfi_filtered (16, "Task Gate");
- break;
- case 6:
- case 7:
- memcpy (&gate, &descr, sizeof gate);
- printf_filtered ("selector=0x%04x offs=0x%04x%04x",
- gate.selector, gate.offset1, gate.offset0);
- printf_filtered (" 16-bit %s Gate",
- descr.stype == 6 ? "Interrupt" : "Trap");
- break;
- case 9:
- case 11:
- printf_filtered (" 32-bit TSS (task %sactive)",
- descr.stype == 3 ? "" : "in");
- break;
- case 12:
- memcpy (&gate, &descr, sizeof gate);
- printf_filtered ("selector=0x%04x offs=0x%04x%04x",
- gate.selector, gate.offset1, gate.offset0);
- printf_filtered (" 32-bit Call Gate (params=%d)",
- gate.param_count);
- break;
- case 14:
- case 15:
- memcpy (&gate, &descr, sizeof gate);
- printf_filtered ("selector=0x%04x offs=0x%04x%04x",
- gate.selector, gate.offset1, gate.offset0);
- printf_filtered (" 32-bit %s Gate",
- descr.stype == 14 ? "Interrupt" : "Trap");
- break;
- case 16: /* data segments */
- case 17:
- case 18:
- case 19:
- case 20:
- case 21:
- case 22:
- case 23:
- printf_filtered (" %s-bit Data (%s Exp-%s%s)",
- descr.bit32 ? "32" : "16",
- descr.stype & 2 ? "Read/Write," : "Read-Only, ",
- descr.stype & 4 ? "down" : "up",
- descr.stype & 1 ? "" : ", N.Acc");
- break;
- case 24: /* code segments */
- case 25:
- case 26:
- case 27:
- case 28:
- case 29:
- case 30:
- case 31:
- printf_filtered (" %s-bit Code (%s, %sConf%s)",
- descr.bit32 ? "32" : "16",
- descr.stype & 2 ? "Exec/Read" : "Exec-Only",
- descr.stype & 4 ? "" : "N.",
- descr.stype & 1 ? "" : ", N.Acc");
- break;
- default:
- printf_filtered ("Unknown type 0x%02x", descr.stype);
- break;
- }
- puts_filtered ("\n");
- }
- else if (force)
- {
- printf_filtered ("0x%03x: ",
- type == 1
- ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
- if (!descr.present)
- puts_filtered ("Segment not present\n");
- else
- printf_filtered ("Segment type 0x%02x is invalid in this table\n",
- descr.stype);
- }
- }
- else if (force)
- printf_filtered ("0x%03x: Cannot read this descriptor\n", idx);
-}
-
-static void
-go32_sldt (char *arg, int from_tty)
+go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr,
+ int len, int rw)
{
- struct dtr_reg gdtr;
- unsigned short ldtr = 0;
- int ldt_idx;
- struct seg_descr ldt_descr;
- long ldt_entry = -1L;
- int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3;
-
- if (arg && *arg)
- {
- while (*arg && isspace(*arg))
- arg++;
+ int align;
+ int size;
+ int rv = 0;
- if (*arg)
- {
- ldt_entry = parse_and_eval_long (arg);
- if (ldt_entry < 0
- || (ldt_entry & 4) == 0
- || (ldt_entry & 3) != (cpl & 3))
- error (_("Invalid LDT entry 0x%03lx."), (unsigned long)ldt_entry);
- }
- }
-
- __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
- __asm__ __volatile__ ("sldt %0" : "=m" (ldtr) : /* no inputs */ );
- ldt_idx = ldtr / 8;
- if (ldt_idx == 0)
- puts_filtered ("There is no LDT.\n");
- /* LDT's entry in the GDT must have the type LDT, which is 2. */
- else if (get_descriptor (gdtr.base, ldt_idx, &ldt_descr) != 2)
- printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n",
- ldt_descr.base0
- | (ldt_descr.base1 << 16)
- | (ldt_descr.base2 << 24));
- else
- {
- unsigned base =
- ldt_descr.base0
- | (ldt_descr.base1 << 16)
- | (ldt_descr.base2 << 24);
- unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16);
- int max_entry;
-
- if (ldt_descr.page_granular)
- /* Page-granular segments must have the low 12 bits of their
- limit set. */
- limit = (limit << 12) | 0xfff;
- /* LDT cannot have more than 8K 8-byte entries, i.e. more than
- 64KB. */
- if (limit > 0xffff)
- limit = 0xffff;
-
- max_entry = (limit + 1) / 8;
-
- if (ldt_entry >= 0)
- {
- if (ldt_entry > limit)
- error (_("Invalid LDT entry %#lx: outside valid limits [0..%#x]"),
- (unsigned long)ldt_entry, limit);
-
- display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
- }
- else
+ static int size_try_array[16] =
+ {
+ 1, 1, 1, 1, /* trying size one */
+ 2, 1, 2, 1, /* trying size two */
+ 2, 1, 2, 1, /* trying size three */
+ 4, 1, 2, 1 /* trying size four */
+ };
+
+ while (len > 0)
+ {
+ align = addr % 4;
+ /* Four is the maximum length for 386. */
+ size = (len > 4) ? 3 : len - 1;
+ size = size_try_array[size * 4 + align];
+ rv = go32_insert_aligned_watchpoint (pid, waddr, addr, size, rw);
+ if (rv)
{
- int i;
-
- for (i = 0; i < max_entry; i++)
- display_descriptor (ldt_descr.stype, base, i, 0);
+ go32_remove_watchpoint (pid, waddr, size);
+ return rv;
}
+ addr += size;
+ len -= size;
}
+ return rv;
}
-static void
-go32_sgdt (char *arg, int from_tty)
-{
- struct dtr_reg gdtr;
- long gdt_entry = -1L;
- int max_entry;
-
- if (arg && *arg)
- {
- while (*arg && isspace(*arg))
- arg++;
-
- if (*arg)
- {
- gdt_entry = parse_and_eval_long (arg);
- if (gdt_entry < 0 || (gdt_entry & 7) != 0)
- error (_("Invalid GDT entry 0x%03lx: not an integral multiple of 8."),
- (unsigned long)gdt_entry);
- }
- }
-
- __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
- max_entry = (gdtr.limit + 1) / 8;
-
- if (gdt_entry >= 0)
- {
- if (gdt_entry > gdtr.limit)
- error (_("Invalid GDT entry %#lx: outside valid limits [0..%#x]"),
- (unsigned long)gdt_entry, gdtr.limit);
-
- display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
- }
- else
- {
- int i;
+/* Remove a watchpoint. */
- for (i = 0; i < max_entry; i++)
- display_descriptor (0, gdtr.base, i, 0);
- }
-}
-
-static void
-go32_sidt (char *arg, int from_tty)
+int
+go32_remove_watchpoint (int pid, CORE_ADDR addr, int len)
{
- struct dtr_reg idtr;
- long idt_entry = -1L;
- int max_entry;
-
- if (arg && *arg)
- {
- while (*arg && isspace(*arg))
- arg++;
-
- if (*arg)
- {
- idt_entry = parse_and_eval_long (arg);
- if (idt_entry < 0)
- error (_("Invalid (negative) IDT entry %ld."), idt_entry);
- }
- }
-
- __asm__ __volatile__ ("sidt %0" : "=m" (idtr) : /* no inputs */ );
- max_entry = (idtr.limit + 1) / 8;
- if (max_entry > 0x100) /* no more than 256 entries */
- max_entry = 0x100;
-
- if (idt_entry >= 0)
- {
- if (idt_entry > idtr.limit)
- error (_("Invalid IDT entry %#lx: outside valid limits [0..%#x]"),
- (unsigned long)idt_entry, idtr.limit);
-
- display_descriptor (1, idtr.base, idt_entry, 1);
- }
- else
- {
- int i;
-
- for (i = 0; i < max_entry; i++)
- display_descriptor (1, idtr.base, i, 0);
- }
-}
-
-/* Cached linear address of the base of the page directory. For
- now, available only under CWSDPMI. Code based on ideas and
- suggestions from Charles Sandmann <sandmann@clio.rice.edu>. */
-static unsigned long pdbr;
+ int i;
-static unsigned long
-get_cr3 (void)
-{
- unsigned offset;
- unsigned taskreg;
- unsigned long taskbase, cr3;
- struct dtr_reg gdtr;
-
- if (pdbr > 0 && pdbr <= 0xfffff)
- return pdbr;
-
- /* Get the linear address of GDT and the Task Register. */
- __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
- __asm__ __volatile__ ("str %0" : "=m" (taskreg) : /* no inputs */ );
-
- /* Task Register is a segment selector for the TSS of the current
- task. Therefore, it can be used as an index into the GDT to get
- at the segment descriptor for the TSS. To get the index, reset
- the low 3 bits of the selector (which give the CPL). Add 2 to the
- offset to point to the 3 low bytes of the base address. */
- offset = gdtr.base + (taskreg & 0xfff8) + 2;
-
-
- /* CWSDPMI's task base is always under the 1MB mark. */
- if (offset > 0xfffff)
- return 0;
-
- _farsetsel (_dos_ds);
- taskbase = _farnspeekl (offset) & 0xffffffU;
- taskbase += _farnspeekl (offset + 2) & 0xff000000U;
- if (taskbase > 0xfffff)
- return 0;
-
- /* CR3 (a.k.a. PDBR, the Page Directory Base Register) is stored at
- offset 1Ch in the TSS. */
- cr3 = _farnspeekl (taskbase + 0x1c) & ~0xfff;
- if (cr3 > 0xfffff)
+ for (i = 0; i <= 3; i++)
{
-#if 0 /* not fullly supported yet */
- /* The Page Directory is in UMBs. In that case, CWSDPMI puts
- the first Page Table right below the Page Directory. Thus,
- the first Page Table's entry for its own address and the Page
- Directory entry for that Page Table will hold the same
- physical address. The loop below searches the entire UMB
- range of addresses for such an occurence. */
- unsigned long addr, pte_idx;
-
- for (addr = 0xb0000, pte_idx = 0xb0;
- pte_idx < 0xff;
- addr += 0x1000, pte_idx++)
+ if (D_REGS[i] == addr)
{
- if (((_farnspeekl (addr + 4 * pte_idx) & 0xfffff027) ==
- (_farnspeekl (addr + 0x1000) & 0xfffff027))
- && ((_farnspeekl (addr + 4 * pte_idx + 4) & 0xfffff000) == cr3))
- {
- cr3 = addr + 0x1000;
- break;
- }
+ DISABLE_REG (i);
}
-#endif
-
- if (cr3 > 0xfffff)
- cr3 = 0;
- }
-
- return cr3;
-}
-
-/* Return the N'th Page Directory entry. */
-static unsigned long
-get_pde (int n)
-{
- unsigned long pde = 0;
-
- if (pdbr && n >= 0 && n < 1024)
- {
- pde = _farpeekl (_dos_ds, pdbr + 4*n);
}
- return pde;
-}
-
-/* Return the N'th entry of the Page Table whose Page Directory entry
- is PDE. */
-static unsigned long
-get_pte (unsigned long pde, int n)
-{
- unsigned long pte = 0;
+ SHOW_DR (remove_watch);
- /* pde & 0x80 tests the 4MB page bit. We don't support 4MB
- page tables, for now. */
- if ((pde & 1) && !(pde & 0x80) && n >= 0 && n < 1024)
- {
- pde &= ~0xfff; /* clear non-address bits */
- pte = _farpeekl (_dos_ds, pde + 4*n);
- }
- return pte;
+ return 0;
}
-/* Display a Page Directory or Page Table entry. IS_DIR, if non-zero,
- says this is a Page Directory entry. If FORCE is non-zero, display
- the entry even if its Present flag is off. OFF is the offset of the
- address from the page's base address. */
-static void
-display_ptable_entry (unsigned long entry, int is_dir, int force, unsigned off)
-{
- if ((entry & 1) != 0)
- {
- printf_filtered ("Base=0x%05lx000", entry >> 12);
- if ((entry & 0x100) && !is_dir)
- puts_filtered (" Global");
- if ((entry & 0x40) && !is_dir)
- puts_filtered (" Dirty");
- printf_filtered (" %sAcc.", (entry & 0x20) ? "" : "Not-");
- printf_filtered (" %sCached", (entry & 0x10) ? "" : "Not-");
- printf_filtered (" Write-%s", (entry & 8) ? "Thru" : "Back");
- printf_filtered (" %s", (entry & 4) ? "Usr" : "Sup");
- printf_filtered (" Read-%s", (entry & 2) ? "Write" : "Only");
- if (off)
- printf_filtered (" +0x%x", off);
- puts_filtered ("\n");
- }
- else if (force)
- printf_filtered ("Page%s not present or not supported; value=0x%lx.\n",
- is_dir ? " Table" : "", entry >> 1);
-}
+/* Check if stopped by a watchpoint. */
-static void
-go32_pde (char *arg, int from_tty)
+CORE_ADDR
+go32_stopped_by_watchpoint (int pid)
{
- long pde_idx = -1, i;
+ int i, ret = 0;
+ int status;
- if (arg && *arg)
+ status = edi.dr[DR_STATUS];
+ SHOW_DR (stopped_by);
+ for (i = 0; i <= 3; i++)
{
- while (*arg && isspace(*arg))
- arg++;
-
- if (*arg)
+ if (WATCH_HIT (i))
{
- pde_idx = parse_and_eval_long (arg);
- if (pde_idx < 0 || pde_idx >= 1024)
- error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
+ SHOW_DR (HIT);
+ ret = D_REGS[i];
}
}
+ /* this is a hack to GDB. If we stopped at a hardware breakpoint,
+ the stop_pc must incremented by DECR_PC_AFTER_BREAK. I tried everything
+ with the DECR_PC_AFTER_HW_BREAK, but nothing works. */
+ /* This is probably fixed by jtc's recent patch -sts 2/19/99 */
+ if (STATUS && !ret)
+ stop_pc += DECR_PC_AFTER_BREAK;
+ STATUS = 0;
- pdbr = get_cr3 ();
- if (!pdbr)
- puts_filtered ("Access to Page Directories is not supported on this system.\n");
- else if (pde_idx >= 0)
- display_ptable_entry (get_pde (pde_idx), 1, 1, 0);
- else
- for (i = 0; i < 1024; i++)
- display_ptable_entry (get_pde (i), 1, 0, 0);
+ return ret;
}
-/* A helper function to display entries in a Page Table pointed to by
- the N'th entry in the Page Directory. If FORCE is non-zero, say
- something even if the Page Table is not accessible. */
-static void
-display_page_table (long n, int force)
-{
- unsigned long pde = get_pde (n);
+/* Remove a breakpoint. */
- if ((pde & 1) != 0)
- {
- int i;
-
- printf_filtered ("Page Table pointed to by Page Directory entry 0x%lx:\n", n);
- for (i = 0; i < 1024; i++)
- display_ptable_entry (get_pte (pde, i), 0, 0, 0);
- puts_filtered ("\n");
- }
- else if (force)
- printf_filtered ("Page Table not present; value=0x%lx.\n", pde >> 1);
-}
-
-static void
-go32_pte (char *arg, int from_tty)
+int
+go32_remove_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
{
- long pde_idx = -1L, i;
-
- if (arg && *arg)
+ int i;
+ for (i = 0; i <= 3; i++)
{
- while (*arg && isspace(*arg))
- arg++;
-
- if (*arg)
+ if (D_REGS[i] == addr)
{
- pde_idx = parse_and_eval_long (arg);
- if (pde_idx < 0 || pde_idx >= 1024)
- error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
+ DISABLE_REG (i);
}
}
-
- pdbr = get_cr3 ();
- if (!pdbr)
- puts_filtered ("Access to Page Tables is not supported on this system.\n");
- else if (pde_idx >= 0)
- display_page_table (pde_idx, 1);
- else
- for (i = 0; i < 1024; i++)
- display_page_table (i, 0);
+ SHOW_DR (remove_hw);
+ return 0;
}
-static void
-go32_pte_for_address (char *arg, int from_tty)
+int
+go32_insert_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
{
- CORE_ADDR addr = 0, i;
+ int i;
+ int read_write_bits, len_bits;
+ int free_debug_register;
+ int register_number;
- if (arg && *arg)
+ /* Look for a free debug register. */
+ for (i = 0; i <= 3; i++)
{
- while (*arg && isspace(*arg))
- arg++;
-
- if (*arg)
- addr = parse_and_eval_address (arg);
+ if (IS_REG_FREE (i))
+ break;
}
- if (!addr)
- error_no_arg (_("linear address"));
- pdbr = get_cr3 ();
- if (!pdbr)
- puts_filtered ("Access to Page Tables is not supported on this system.\n");
- else
- {
- int pde_idx = (addr >> 22) & 0x3ff;
- int pte_idx = (addr >> 12) & 0x3ff;
- unsigned offs = addr & 0xfff;
+ /* No more debug registers! */
+ if (i > 3)
+ return -1;
- printf_filtered ("Page Table entry for address 0x%llx:\n",
- (unsigned long long)addr);
- display_ptable_entry (get_pte (get_pde (pde_idx), pte_idx), 0, 1, offs);
- }
+ SET_BREAK (i, addr);
+ LOCAL_ENABLE_REG (i);
+ SHOW_DR (insert_hw);
+
+ return 0;
}
-static struct cmd_list_element *info_dos_cmdlist = NULL;
+static struct target_ops go32_ops;
static void
-go32_info_dos_command (char *args, int from_tty)
+init_go32_ops (void)
{
- help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
+ go32_ops.to_shortname = "djgpp";
+ go32_ops.to_longname = "djgpp target process";
+ go32_ops.to_doc =
+ "Program loaded by djgpp, when gdb is used as an external debugger";
+ go32_ops.to_open = go32_open;
+ go32_ops.to_close = go32_close;
+ go32_ops.to_detach = go32_detach;
+ go32_ops.to_resume = go32_resume;
+ go32_ops.to_wait = go32_wait;
+ go32_ops.to_fetch_registers = go32_fetch_registers;
+ go32_ops.to_store_registers = go32_store_registers;
+ go32_ops.to_prepare_to_store = go32_prepare_to_store;
+ go32_ops.to_xfer_memory = go32_xfer_memory;
+ go32_ops.to_files_info = go32_files_info;
+ go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
+ go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
+ go32_ops.to_terminal_init = ignore;
+ go32_ops.to_terminal_inferior = ignore;
+ go32_ops.to_terminal_ours_for_output = ignore;
+ go32_ops.to_terminal_ours = ignore;
+ go32_ops.to_terminal_info = ignore2;
+ go32_ops.to_kill = go32_kill_inferior;
+ go32_ops.to_create_inferior = go32_create_inferior;
+ go32_ops.to_mourn_inferior = go32_mourn_inferior;
+ go32_ops.to_can_run = go32_can_run;
+ go32_ops.to_stop = go32_stop;
+ go32_ops.to_stratum = process_stratum;
+ go32_ops.to_has_all_memory = 1;
+ go32_ops.to_has_memory = 1;
+ go32_ops.to_has_stack = 1;
+ go32_ops.to_has_registers = 1;
+ go32_ops.to_has_execution = 1;
+ go32_ops.to_magic = OPS_MAGIC;
}
void
@@ -1909,61 +751,4 @@ _initialize_go32_nat (void)
{
init_go32_ops ();
add_target (&go32_ops);
-
- add_prefix_cmd ("dos", class_info, go32_info_dos_command, _("\
-Print information specific to DJGPP (aka MS-DOS) debugging."),
- &info_dos_cmdlist, "info dos ", 0, &infolist);
-
- add_cmd ("sysinfo", class_info, go32_sysinfo, _("\
-Display information about the target system, including CPU, OS, DPMI, etc."),
- &info_dos_cmdlist);
- add_cmd ("ldt", class_info, go32_sldt, _("\
-Display entries in the LDT (Local Descriptor Table).\n\
-Entry number (an expression) as an argument means display only that entry."),
- &info_dos_cmdlist);
- add_cmd ("gdt", class_info, go32_sgdt, _("\
-Display entries in the GDT (Global Descriptor Table).\n\
-Entry number (an expression) as an argument means display only that entry."),
- &info_dos_cmdlist);
- add_cmd ("idt", class_info, go32_sidt, _("\
-Display entries in the IDT (Interrupt Descriptor Table).\n\
-Entry number (an expression) as an argument means display only that entry."),
- &info_dos_cmdlist);
- add_cmd ("pde", class_info, go32_pde, _("\
-Display entries in the Page Directory.\n\
-Entry number (an expression) as an argument means display only that entry."),
- &info_dos_cmdlist);
- add_cmd ("pte", class_info, go32_pte, _("\
-Display entries in Page Tables.\n\
-Entry number (an expression) as an argument means display only entries\n\
-from the Page Table pointed to by the specified Page Directory entry."),
- &info_dos_cmdlist);
- add_cmd ("address-pte", class_info, go32_pte_for_address, _("\
-Display a Page Table entry for a linear address.\n\
-The address argument must be a linear address, after adding to\n\
-it the base address of the appropriate segment.\n\
-The base address of variables and functions in the debuggee's data\n\
-or code segment is stored in the variable __djgpp_base_address,\n\
-so use `__djgpp_base_address + (char *)&var' as the argument.\n\
-For other segments, look up their base address in the output of\n\
-the `info dos ldt' command."),
- &info_dos_cmdlist);
-}
-
-pid_t
-tcgetpgrp (int fd)
-{
- if (isatty (fd))
- return SOME_PID;
- errno = ENOTTY;
- return -1;
-}
-
-int
-tcsetpgrp (int fd, pid_t pgid)
-{
- if (isatty (fd) && pgid == SOME_PID)
- return 0;
- errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
- return -1;
}
diff --git a/gdb/tic80-tdep.c b/gdb/tic80-tdep.c
new file mode 100644
index 00000000000..0abbb80dc1a
--- /dev/null
+++ b/gdb/tic80-tdep.c
@@ -0,0 +1,483 @@
+/* Target-dependent code for the TI TMS320C80 (MVP) for GDB, the GNU debugger.
+ Copyright 1996, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "value.h"
+#include "frame.h"
+#include "inferior.h"
+#include "obstack.h"
+#include "target.h"
+#include "bfd.h"
+#include "gdb_string.h"
+#include "gdbcore.h"
+#include "symfile.h"
+
+/* Function: frame_find_saved_regs
+ Return the frame_saved_regs structure for the frame.
+ Doesn't really work for dummy frames, but it does pass back
+ an empty frame_saved_regs, so I guess that's better than total failure */
+
+void
+tic80_frame_find_saved_regs (fi, regaddr)
+ struct frame_info *fi;
+ struct frame_saved_regs *regaddr;
+{
+ memcpy (regaddr, &fi->fsr, sizeof (struct frame_saved_regs));
+}
+
+/* Function: skip_prologue
+ Find end of function prologue. */
+
+CORE_ADDR
+tic80_skip_prologue (pc)
+ CORE_ADDR pc;
+{
+ CORE_ADDR func_addr, func_end;
+ struct symtab_and_line sal;
+
+ /* See what the symbol table says */
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.line != 0 && sal.end < func_end)
+ return sal.end;
+ else
+ /* Either there's no line info, or the line after the prologue is after
+ the end of the function. In this case, there probably isn't a
+ prologue. */
+ return pc;
+ }
+
+ /* We can't find the start of this function, so there's nothing we can do. */
+ return pc;
+}
+
+/* Function: tic80_scan_prologue
+ This function decodes the target function prologue to determine:
+ 1) the size of the stack frame
+ 2) which registers are saved on it
+ 3) the offsets of saved regs
+ 4) the frame size
+ This information is stored in the "extra" fields of the frame_info. */
+
+static void
+tic80_scan_prologue (fi)
+ struct frame_info *fi;
+{
+ struct symtab_and_line sal;
+ CORE_ADDR prologue_start, prologue_end, current_pc;
+
+ /* Assume there is no frame until proven otherwise. */
+ fi->framereg = SP_REGNUM;
+ fi->framesize = 0;
+ fi->frameoffset = 0;
+
+ /* this code essentially duplicates skip_prologue,
+ but we need the start address below. */
+
+ if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ {
+ sal = find_pc_line (prologue_start, 0);
+
+ if (sal.line == 0) /* no line info, use current PC */
+ if (prologue_start != entry_point_address ())
+ prologue_end = fi->pc;
+ else
+ return; /* _start has no frame or prologue */
+ else if (sal.end < prologue_end) /* next line begins after fn end */
+ prologue_end = sal.end; /* (probably means no prologue) */
+ }
+ else
+/* FIXME */
+ prologue_end = prologue_start + 40; /* We're in the boondocks: allow for */
+ /* 16 pushes, an add, and "mv fp,sp" */
+
+ prologue_end = min (prologue_end, fi->pc);
+
+ /* Now search the prologue looking for instructions that set up the
+ frame pointer, adjust the stack pointer, and save registers. */
+
+ for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 4)
+ {
+ unsigned int insn;
+ int regno;
+ int offset = 0;
+
+ insn = read_memory_unsigned_integer (current_pc, 4);
+
+ if ((insn & 0x301000) == 0x301000) /* Long immediate? */
+/* FIXME - set offset for long immediate instructions */
+ current_pc += 4;
+ else
+ {
+ offset = insn & 0x7fff; /* extract 15-bit offset */
+ if (offset & 0x4000) /* if negative, sign-extend */
+ offset = -(0x8000 - offset);
+ }
+
+ if ((insn & 0x7fd0000) == 0x590000) /* st.{w,d} reg, xx(r1) */
+ {
+ regno = ((insn >> 27) & 0x1f);
+ fi->fsr.regs[regno] = offset;
+ if (insn & 0x8000) /* 64-bit store (st.d)? */
+ fi->fsr.regs[regno+1] = offset+4;
+ }
+ else if ((insn & 0xffff8000) == 0x086c8000) /* addu xx, r1, r1 */
+ fi->framesize = -offset;
+ else if ((insn & 0xffff8000) == 0xf06c8000) /* addu xx, r1, r30 */
+ {
+ fi->framereg = FP_REGNUM; /* fp is now valid */
+ fi->frameoffset = offset;
+ break; /* end of stack adjustments */
+ }
+ else if (insn == 0xf03b2001) /* addu r1, r0, r30 */
+ {
+ fi->framereg = FP_REGNUM; /* fp is now valid */
+ fi->frameoffset = 0;
+ break; /* end of stack adjustments */
+ }
+ else
+/* FIXME - handle long immediate instructions */
+ break; /* anything else isn't prologue */
+ }
+}
+
+/* Function: init_extra_frame_info
+ This function actually figures out the frame address for a given pc and
+ sp. This is tricky on the c80 because we sometimes don't use an explicit
+ frame pointer, and the previous stack pointer isn't necessarily recorded
+ on the stack. The only reliable way to get this info is to
+ examine the prologue. */
+
+void
+tic80_init_extra_frame_info (fi)
+ struct frame_info *fi;
+{
+ int reg;
+
+ if (fi->next)
+ fi->pc = FRAME_SAVED_PC (fi->next);
+
+ /* Because zero is a valid register offset relative to SP, we initialize
+ the offsets to -1 to indicate unused entries. */
+ for (reg = 0; reg < NUM_REGS; reg++)
+ fi->fsr.regs[reg] = -1;
+
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ {
+ /* We need to setup fi->frame here because run_stack_dummy gets it wrong
+ by assuming it's always FP. */
+ fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
+ fi->framesize = 0;
+ fi->frameoffset = 0;
+ return;
+ }
+ else
+ {
+ tic80_scan_prologue (fi);
+
+ if (!fi->next) /* this is the innermost frame? */
+ fi->frame = read_register (fi->framereg);
+ else /* not the innermost frame */
+ /* If this function uses FP as the frame register, and the function
+ it called saved the FP, get the saved FP. */
+ if (fi->framereg == FP_REGNUM &&
+ fi->next->fsr.regs[FP_REGNUM] != (unsigned) -1)
+ fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4);
+
+ /* Convert SP-relative offsets of saved registers to real addresses. */
+ for (reg = 0; reg < NUM_REGS; reg++)
+ if (fi->fsr.regs[reg] == (unsigned) -1)
+ fi->fsr.regs[reg] = 0; /* unused entry */
+ else
+ fi->fsr.regs[reg] += fi->frame - fi->frameoffset;
+ }
+}
+
+/* Function: find_callers_reg
+ Find REGNUM on the stack. Otherwise, it's in an active register. One thing
+ we might want to do here is to check REGNUM against the clobber mask, and
+ somehow flag it as invalid if it isn't saved on the stack somewhere. This
+ would provide a graceful failure mode when trying to get the value of
+ caller-saves registers for an inner frame. */
+
+CORE_ADDR
+tic80_find_callers_reg (fi, regnum)
+ struct frame_info *fi;
+ int regnum;
+{
+ for (; fi; fi = fi->next)
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, regnum);
+ else if (fi->fsr.regs[regnum] != 0)
+ return read_memory_integer (fi->fsr.regs[regnum],
+ REGISTER_RAW_SIZE(regnum));
+ return read_register (regnum);
+}
+
+/* Function: frame_chain
+ Given a GDB frame, determine the address of the calling function's frame.
+ This will be used to create a new GDB frame struct, and then
+ INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+ For c80, we save the frame size when we initialize the frame_info. */
+
+CORE_ADDR
+tic80_frame_chain (fi)
+ struct frame_info *fi;
+{
+ CORE_ADDR fn_start, callers_pc, fp;
+
+ /* is this a dummy frame? */
+ if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame))
+ return fi->frame; /* dummy frame same as caller's frame */
+
+ /* is caller-of-this a dummy frame? */
+ callers_pc = FRAME_SAVED_PC(fi); /* find out who called us: */
+ fp = tic80_find_callers_reg (fi, FP_REGNUM);
+ if (PC_IN_CALL_DUMMY(callers_pc, fp, fp))
+ return fp; /* dummy frame's frame may bear no relation to ours */
+
+ if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
+ if (fn_start == entry_point_address ())
+ return 0; /* in _start fn, don't chain further */
+
+ if (fi->framereg == FP_REGNUM)
+ return tic80_find_callers_reg (fi, FP_REGNUM);
+ else
+ return fi->frame + fi->framesize;
+}
+
+/* Function: pop_frame
+ Discard from the stack the innermost frame,
+ restoring all saved registers. */
+
+struct frame_info *
+tic80_pop_frame (frame)
+ struct frame_info *frame;
+{
+ int regnum;
+
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ generic_pop_dummy_frame ();
+ else
+ {
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (frame->fsr.regs[regnum] != 0)
+ write_register (regnum,
+ read_memory_integer (frame->fsr.regs[regnum], 4));
+
+ write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
+ write_register (SP_REGNUM, read_register (FP_REGNUM));
+#if 0
+ if (read_register (PSW_REGNUM) & 0x80)
+ write_register (SPU_REGNUM, read_register (SP_REGNUM));
+ else
+ write_register (SPI_REGNUM, read_register (SP_REGNUM));
+#endif
+ }
+ flush_cached_frames ();
+ return NULL;
+}
+
+/* Function: frame_saved_pc
+ Find the caller of this frame. We do this by seeing if LR_REGNUM is saved
+ in the stack anywhere, otherwise we get it from the registers. */
+
+CORE_ADDR
+tic80_frame_saved_pc (fi)
+ struct frame_info *fi;
+{
+ if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+ else
+ return tic80_find_callers_reg (fi, LR_REGNUM);
+}
+
+/* Function: tic80_push_return_address (pc, sp)
+ Set up the return address for the inferior function call.
+ Necessary for targets that don't actually execute a JSR/BSR instruction
+ (ie. when using an empty CALL_DUMMY) */
+
+CORE_ADDR
+tic80_push_return_address (pc, sp)
+ CORE_ADDR pc;
+ CORE_ADDR sp;
+{
+ write_register (LR_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+
+/* Function: push_arguments
+ Setup the function arguments for calling a function in the inferior.
+
+ On the TI C80 architecture, there are six register pairs (R2/R3 to R12/13)
+ which are dedicated for passing function arguments. Up to the first six
+ arguments (depending on size) may go into these registers.
+ The rest go on the stack.
+
+ Arguments that are smaller than 4 bytes will still take up a whole
+ register or a whole 32-bit word on the stack, and will be
+ right-justified in the register or the stack word. This includes
+ chars, shorts, and small aggregate types.
+
+ Arguments that are four bytes or less in size are placed in the
+ even-numbered register of a register pair, and the odd-numbered
+ register is not used.
+
+ Arguments of 8 bytes size (such as floating point doubles) are placed
+ in a register pair. The least significant 32-bit word is placed in
+ the even-numbered register, and the most significant word in the
+ odd-numbered register.
+
+ Aggregate types with sizes between 4 and 8 bytes are passed
+ entirely on the stack, and are left-justified within the
+ double-word (as opposed to aggregates smaller than 4 bytes
+ which are right-justified).
+
+ Aggregates of greater than 8 bytes are first copied onto the stack,
+ and then a pointer to the copy is passed in the place of the normal
+ argument (either in a register if available, or on the stack).
+
+ Functions that must return an aggregate type can return it in the
+ normal return value registers (R2 and R3) if its size is 8 bytes or
+ less. For larger return values, the caller must allocate space for
+ the callee to copy the return value to. A pointer to this space is
+ passed as an implicit first argument, always in R0. */
+
+CORE_ADDR
+tic80_push_arguments (nargs, args, sp, struct_return, struct_addr)
+ int nargs;
+ value_ptr *args;
+ CORE_ADDR sp;
+ unsigned char struct_return;
+ CORE_ADDR struct_addr;
+{
+ int stack_offset, stack_alloc;
+ int argreg;
+ int argnum;
+ struct type *type;
+ CORE_ADDR regval;
+ char *val;
+ char valbuf[4];
+ int len;
+ int odd_sized_struct;
+ int is_struct;
+
+ /* first force sp to a 4-byte alignment */
+ sp = sp & ~3;
+
+ argreg = ARG0_REGNUM;
+ /* The "struct return pointer" pseudo-argument goes in R0 */
+ if (struct_return)
+ write_register (argreg++, struct_addr);
+
+ /* Now make sure there's space on the stack */
+ for (argnum = 0, stack_alloc = 0;
+ argnum < nargs; argnum++)
+ stack_alloc += ((TYPE_LENGTH(VALUE_TYPE(args[argnum])) + 3) & ~3);
+ sp -= stack_alloc; /* make room on stack for args */
+
+
+ /* Now load as many as possible of the first arguments into
+ registers, and push the rest onto the stack. There are 16 bytes
+ in four registers available. Loop thru args from first to last. */
+
+ argreg = ARG0_REGNUM;
+ for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
+ {
+ type = VALUE_TYPE (args[argnum]);
+ len = TYPE_LENGTH (type);
+ memset (valbuf, 0, sizeof (valbuf));
+ val = (char *) VALUE_CONTENTS (args[argnum]);
+
+/* FIXME -- tic80 can take doubleword arguments in register pairs */
+ is_struct = (type->code == TYPE_CODE_STRUCT);
+ odd_sized_struct = 0;
+
+ if (! is_struct)
+ {
+ if (len < 4)
+ { /* value gets right-justified in the register or stack word */
+ memcpy (valbuf + (4 - len), val, len);
+ val = valbuf;
+ }
+ if (len > 4 && (len & 3) != 0)
+ odd_sized_struct = 1; /* such structs go entirely on stack */
+ }
+ else
+ {
+ /* Structs are always passed by reference. */
+ write_register (argreg, sp + stack_offset);
+ argreg ++;
+ }
+
+ while (len > 0)
+ {
+ if (is_struct || argreg > ARGLAST_REGNUM || odd_sized_struct)
+ { /* must go on the stack */
+ write_memory (sp + stack_offset, val, 4);
+ stack_offset += 4;
+ }
+ /* NOTE WELL!!!!! This is not an "else if" clause!!!
+ That's because some things get passed on the stack
+ AND in the registers! */
+ if (!is_struct && argreg <= ARGLAST_REGNUM)
+ { /* there's room in a register */
+ regval = extract_address (val, REGISTER_RAW_SIZE(argreg));
+ write_register (argreg, regval);
+ argreg += 2; /* FIXME -- what about doubleword args? */
+ }
+ /* Store the value 4 bytes at a time. This means that things
+ larger than 4 bytes may go partly in registers and partly
+ on the stack. */
+ len -= REGISTER_RAW_SIZE(argreg);
+ val += REGISTER_RAW_SIZE(argreg);
+ }
+ }
+ return sp;
+}
+
+/* Function: tic80_write_sp
+ Because SP is really a read-only register that mirrors either SPU or SPI,
+ we must actually write one of those two as well, depending on PSW. */
+
+void
+tic80_write_sp (val)
+ CORE_ADDR val;
+{
+#if 0
+ unsigned long psw = read_register (PSW_REGNUM);
+
+ if (psw & 0x80) /* stack mode: user or interrupt */
+ write_register (SPU_REGNUM, val);
+ else
+ write_register (SPI_REGNUM, val);
+#endif
+ write_register (SP_REGNUM, val);
+}
+
+void
+_initialize_tic80_tdep ()
+{
+ tm_print_insn = print_insn_tic80;
+}
+