home *** CD-ROM | disk | FTP | other *** search
GNU Info File | 1993-06-12 | 42.2 KB | 980 lines |
- This is Info file gdbint.info, produced by Makeinfo-1.47 from the input
- file gdbint.tex.
-
- START-INFO-DIR-ENTRY
- * Gdb-Internals: (gdbint). The GNU debugger's internals.
- END-INFO-DIR-ENTRY
-
- This file documents the internals of the GNU debugger GDB.
-
- Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
- Contributed by Cygnus Support. Written by John Gilmore.
-
- Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
-
- Permission is granted to copy or distribute modified versions of this
- manual under the terms of the GPL (for which purpose this text may be
- regarded as a program in the language TeX).
-
- File: gdbint.info, Node: Top, Next: README, Prev: (DIR), Up: (DIR)
-
-
-
- This documents the internals of the GNU debugger, GDB. It is a
- collection of miscellaneous information with little form at this point.
- Mostly, it is a repository into which you can put information about GDB
- as you discover it (or as you design changes to GDB).
-
- * Menu:
-
- * README:: The README File
- * New Architectures:: Defining a New Host or Target Architecture
- * Config:: Adding a New Configuration
- * Host:: Adding a New Host
- * Native:: Adding a New Native Configuration
- * Target:: Adding a New Target
- * Languages:: Defining New Source Languages
- * Releases:: Configuring GDB for Release
- * Partial Symbol Tables:: How GDB reads symbols quickly at startup
- * BFD support for GDB:: How BFD and GDB interface
- * Symbol Reading:: Defining New Symbol Readers
- * Cleanups:: Cleanups
- * Wrapping:: Wrapping Output Lines
- * Frames:: Keeping track of function calls
- * Coding Style:: Strunk and White for GDB maintainers
- * Host Conditionals:: What features exist in the host
- * Target Conditionals:: What features exist in the target
- * Native Conditionals:: Conditionals for when host and target are same
- * Obsolete Conditionals:: Conditionals that don't exist any more
-
- File: gdbint.info, Node: README, Next: New Architectures, Prev: Top, Up: Top
-
- The `README' File
- *****************
-
- Check the `README' file, it often has useful information that does
- not appear anywhere else in the directory.
-
- File: gdbint.info, Node: New Architectures, Next: Config, Prev: README, Up: Top
-
- Defining a New Host or Target Architecture
- ******************************************
-
- When building support for a new host and/or target, much of the work
- you need to do is handled by specifying configuration files; *note
- Adding a New Configuration: Config.. Further work can be divided into
- "host-dependent" (*note Adding a New Host: Host.) and
- "target-dependent" (*note Adding a New Target: Target.). The following
- discussion is meant to explain the difference between hosts and targets.
-
- What is considered "host-dependent" versus "target-dependent"?
- ==============================================================
-
- "Host" refers to attributes of the system where GDB runs. "Target"
- refers to the system where the program being debugged executes. In
- most cases they are the same machine, in which case a third type of
- "Native" attributes come into play.
-
- Defines and include files needed to build on the host are host
- support. Examples are tty support, system defined types, host byte
- order, host float format.
-
- Defines and information needed to handle the target format are target
- dependent. Examples are the stack frame format, instruction set,
- breakpoint instruction, registers, and how to set up and tear down the
- stack to call a function.
-
- Information that is only needed when the host and target are the
- same, is native dependent. One example is Unix child process support;
- if the host and target are not the same, doing a fork to start the
- target process is a bad idea. The various macros needed for finding the
- registers in the `upage', running `ptrace', and such are all in the
- native-dependent files.
-
- Another example of native-dependent code is support for features
- that are really part of the target environment, but which require
- `#include' files that are only available on the host system. Core file
- handling and `setjmp' handling are two common cases.
-
- When you want to make GDB work "native" on a particular machine, you
- have to include all three kinds of information.
-
- The dependent information in GDB is organized into files by naming
- conventions.
-
- Host-Dependent Files
- `config/*.mh'
- Sets Makefile parameters
-
- `xm-*.h'
- Global #include's and #define's and definitions
-
- `*-xdep.c'
- Global variables and functions
-
- Native-Dependent Files
- `config/*.mh'
- Sets Makefile parameters (for *both* host and native)
-
- `nm-*.h'
- #include's and #define's and definitions. This file is only
- included by the small number of modules that need it, so beware of
- doing feature-test #define's from its macros.
-
- `*-nat.c'
- global variables and functions
-
- Target-Dependent Files
- `config/*.mt'
- Sets Makefile parameters
-
- `tm-*.h'
- Global #include's and #define's and definitions
-
- `*-tdep.c'
- Global variables and functions
-
- At this writing, most supported hosts have had their host and native
- dependencies sorted out properly. There are a few stragglers, which
- can be recognized by the absence of NATDEPFILES lines in their
- `config/*.mh'.
-
- File: gdbint.info, Node: Config, Next: Host, Prev: New Architectures, Up: Top
-
- Adding a New Configuration
- **************************
-
- Most of the work in making GDB compile on a new machine is in
- specifying the configuration of the machine. This is done in a
- dizzying variety of header files and configuration scripts, which we
- hope to make more sensible soon. Let's say your new host is called an
- XXX (e.g. `sun4'), and its full three-part configuration name is
- `XARCH-XVEND-XOS' (e.g. `sparc-sun-sunos4'). In particular:
-
- In the top level directory, edit `config.sub' and add XARCH, XVEND,
- and XOS to the lists of supported architectures, vendors, and operating
- systems near the bottom of the file. Also, add XXX as an alias that
- maps to `XARCH-XVEND-XOS'. You can test your changes by running
-
- ./config.sub XXX
-
- and
- ./config.sub `XARCH-XVEND-XOS'
-
- which should both respond with `XARCH-XVEND-XOS' and no error messages.
-
- Now, go to the `bfd' directory and create a new file
- `bfd/hosts/h-XXX.h'. Examine the other `h-*.h' files as templates, and
- create one that brings in the right include files for your system, and
- defines any host-specific macros needed by BFD, the Binutils, GNU LD,
- or the Opcodes directories. (They all share the bfd `hosts' directory
- and the `configure.host' file.)
-
- Then edit `bfd/configure.host'. Add a line to recognize your
- `XARCH-XVEND-XOS' configuration, and set `my_host' to XXX when you
- recognize it. This will cause your file `h-XXX.h' to be linked to
- `sysdep.h' at configuration time. When creating the line that
- recognizes your configuration, only match the fields that you really
- need to match; e.g. don't match match the architecture or manufacturer
- if the OS is sufficient to distinguish the configuration that your
- `h-XXX.h' file supports. Don't match the manufacturer name unless you
- really need to. This should make future ports easier.
-
- Also, if this host requires any changes to the Makefile, create a
- file `bfd/config/XXX.mh', which includes the required lines.
-
- It's possible that the `libiberty' and `readline' directories won't
- need any changes for your configuration, but if they do, you can change
- the `configure.in' file there to recognize your system and map to an
- `mh-XXX' file. Then add `mh-XXX' to the `config/' subdirectory, to set
- any makefile variables you need. The only current options in there are
- things like `-DSYSV'. (This `mh-XXX' naming convention differs from
- elsewhere in GDB, by historical accident. It should be cleaned up so
- that all such files are called `XXX.mh'.)
-
- Aha! Now to configure GDB itself! Edit `gdb/configure.in' to
- recognize your system and set `gdb_host' to XXX, and (unless your
- desired target is already available) also set `gdb_target' to something
- appropriate (for instance, XXX). To handle new hosts, modify the
- segment after the comment `# per-host'; to handle new targets, modify
- after `# per-target'.
-
- Finally, you'll need to specify and define GDB's host-, native-, and
- target-dependent `.h' and `.c' files used for your configuration; the
- next two chapters discuss those.
-
- File: gdbint.info, Node: Host, Next: Native, Prev: Config, Up: Top
-
- Adding a New Host
- *****************
-
- Once you have specified a new configuration for your host (*note
- Adding a New Configuration: Config.), there are three remaining pieces
- to making GDB work on a new machine. First, you have to make it host
- on the new machine (compile there, handle that machine's terminals
- properly, etc). If you will be cross-debugging to some other kind of
- system that's already supported, you are done.
-
- If you want to use GDB to debug programs that run on the new machine,
- you have to get it to understand the machine's object files, symbol
- files, and interfaces to processes; *note Adding a New Target: Target.
- and *note Adding a New Native Configuration: Native.
-
- Several files control GDB's configuration for host systems:
-
- `gdb/config/mh-XXX'
- Specifies Makefile fragments needed when hosting on machine XXX.
- In particular, this lists the required machine-dependent object
- files, by defining `XDEPFILES=...'. Also specifies the header
- file which describes host XXX, by defining `XM_FILE= xm-XXX.h'.
- You can also define `CC', `REGEX' and `REGEX1', `SYSV_DEFINE',
- `XM_CFLAGS', `XM_ADD_FILES', `XM_CLIBS', `XM_CDEPS', etc.; see
- `Makefile.in'.
-
- `gdb/xm-XXX.h'
- (`xm.h' is a link to this file, created by configure). Contains C
- macro definitions describing the host system environment, such as
- byte order, host C compiler and library, ptrace support, and core
- file structure. Crib from existing `xm-*.h' files to create a new
- one.
-
- `gdb/XXX-xdep.c'
- Contains any miscellaneous C code required for this machine as a
- host. On many machines it doesn't exist at all. If it does
- exist, put `XXX-xdep.o' into the `XDEPFILES' line in
- `gdb/config/mh-XXX'.
-
- Generic Host Support Files
- --------------------------
-
- There are some "generic" versions of routines that can be used by
- various systems. These can be customized in various ways by macros
- defined in your `xm-XXX.h' file. If these routines work for the XXX
- host, you can just include the generic file's name (with `.o', not
- `.c') in `XDEPFILES'.
-
- Otherwise, if your machine needs custom support routines, you will
- need to write routines that perform the same functions as the generic
- file. Put them into `XXX-xdep.c', and put `XXX-xdep.o' into `XDEPFILES'.
-
- `ser-bsd.c'
- This contains serial line support for Berkeley-derived Unix
- systems.
-
- `ser-go32.c'
- This contains serial line support for 32-bit programs running
- under DOS using the GO32 execution environment.
-
- `ser-termios.c'
- This contains serial line support for System V-derived Unix
- systems.
-
- Now, you are now ready to try configuring GDB to compile using your
- system as its host. From the top level (above `bfd', `gdb', etc), do:
-
- ./configure XXX +target=vxworks960
-
- This will configure your system to cross-compile for VxWorks on the
- Intel 960, which is probably not what you really want, but it's a test
- case that works at this stage. (You haven't set up to be able to debug
- programs that run *on* XXX yet.)
-
- If this succeeds, you can try building it all with:
-
- make
-
- Repeat until the program configures, compiles, links, and runs. When
- run, it won't be able to do much (unless you have a VxWorks/960 board
- on your network) but you will know that the host support is pretty well
- done.
-
- Good luck! Comments and suggestions about this section are
- particularly welcome; send them to `bug-gdb@prep.ai.mit.edu'.
-
- File: gdbint.info, Node: Native, Next: Target, Prev: Host, Up: Top
-
- Adding a New Native Configuration
- *********************************
-
- If you are making GDB run native on the XXX machine, you have plenty
- more work to do. Several files control GDB's configuration for native
- support:
-
- `gdb/config/XXX.mh'
- Specifies Makefile fragments needed when hosting *or native* on
- machine XXX. In particular, this lists the required
- native-dependent object files, by defining `NATDEPFILES=...'. Also
- specifies the header file which describes native support on XXX,
- by defining `NM_FILE= nm-XXX.h'. You can also define `NAT_CFLAGS',
- `NAT_ADD_FILES', `NAT_CLIBS', `NAT_CDEPS', etc.; see `Makefile.in'.
-
- `gdb/nm-XXX.h'
- (`nm.h' is a link to this file, created by configure). Contains C
- macro definitions describing the native system environment, such
- as child process control and core file support. Crib from existing
- `nm-*.h' files to create a new one. Code that needs these
- definitions will have to `#include "nm.h"' explicitly, since it is
- not included by `defs.h'.
-
- `gdb/XXX-nat.c'
- Contains any miscellaneous C code required for this native support
- of this machine. On some machines it doesn't exist at all.
-
- Generic Native Support Files
- ----------------------------
-
- There are some "generic" versions of routines that can be used by
- various systems. These can be customized in various ways by macros
- defined in your `nm-XXX.h' file. If these routines work for the XXX
- host, you can just include the generic file's name (with `.o', not
- `.c') in `NATDEPFILES'.
-
- Otherwise, if your machine needs custom support routines, you will
- need to write routines that perform the same functions as the generic
- file. Put them into `XXX-nat.c', and put `XXX-nat.o' into `NATDEPFILES'.
-
- `inftarg.c'
- This contains the *target_ops vector* that supports Unix child
- processes on systems which use ptrace and wait to control the
- child.
-
- `procfs.c'
- This contains the *target_ops vector* that supports Unix child
- processes on systems which use /proc to control the child.
-
- `fork-child.c'
- This does the low-level grunge that uses Unix system calls to do a
- "fork and exec" to start up a child process.
-
- `infptrace.c'
- This is the low level interface to inferior processes for systems
- using the Unix `ptrace' call in a vanilla way.
-
- `coredep.c::fetch_core_registers()'
- Support for reading registers out of a core file. This routine
- calls `register_addr()', see below. Now that BFD is used to read
- core files, virtually all machines should use `coredep.c', and
- should just provide `fetch_core_registers' in `XXX-nat.c' (or
- `REGISTER_U_ADDR' in `nm-XXX.h').
-
- `coredep.c::register_addr()'
- If your `nm-XXX.h' file defines the macro `REGISTER_U_ADDR(addr,
- blockend, regno)', it should be defined to set `addr' to the
- offset within the `user' struct of GDB register number `regno'.
- `blockend' is the offset within the "upage" of `u.u_ar0'. If
- `REGISTER_U_ADDR' is defined, `coredep.c' will define the
- `register_addr()' function and use the macro in it. If you do not
- define `REGISTER_U_ADDR', but you are using the standard
- `fetch_core_registers()', you will need to define your own version
- of `register_addr()', put it into your `XXX-nat.c' file, and be
- sure `XXX-nat.o' is in the `NATDEPFILES' list. If you have your
- own `fetch_core_registers()', you may not need a separate
- `register_addr()'. Many custom `fetch_core_registers()'
- implementations simply locate the registers themselves.
-
- When making GDB run native on a new operating system, to make it
- possible to debug core files, you will need to either write specific
- code for parsing your OS's core files, or customize `bfd/trad-core.c'.
- First, use whatever `#include' files your machine uses to define the
- struct of registers that is accessible (possibly in the u-area) in a
- core file (rather than `machine/reg.h'), and an include file that
- defines whatever header exists on a core file (e.g. the u-area or a
- `struct core'). Then modify `trad_unix_core_file_p()' to use these
- values to set up the section information for the data segment, stack
- segment, any other segments in the core file (perhaps shared library
- contents or control information), "registers" segment, and if there are
- two discontiguous sets of registers (e.g. integer and float), the
- "reg2" segment. This section information basically delimits areas in
- the core file in a standard way, which the section-reading routines in
- BFD know how to seek around in.
-
- Then back in GDB, you need a matching routine called
- `fetch_core_registers()'. If you can use the generic one, it's in
- `coredep.c'; if not, it's in your `XXX-nat.c' file. It will be passed a
- char pointer to the entire "registers" segment, its length, and a zero;
- or a char pointer to the entire "regs2" segment, its length, and a 2.
- The routine should suck out the supplied register values and install
- them into GDB's "registers" array. (*Note Defining a New Host or Target
- Architecture: New Architectures, for more info about this.)
-
- If your system uses `/proc' to control processes, and uses ELF
- format core files, then you may be able to use the same routines for
- reading the registers out of processes and out of core files.
-
- File: gdbint.info, Node: Target, Next: Languages, Prev: Native, Up: Top
-
- Adding a New Target
- *******************
-
- For a new target called TTT, first specify the configuration as
- described in *Note Adding a New Configuration: Config. If your new
- target is the same as your new host, you've probably already done that.
-
- A variety of files specify attributes of the GDB target environment:
-
- `gdb/config/TTT.mt'
- Contains a Makefile fragment specific to this target. Specifies
- what object files are needed for target TTT, by defining
- `TDEPFILES=...'. Also specifies the header file which describes
- TTT, by defining `TM_FILE= tm-TTT.h'. You can also define
- `TM_CFLAGS', `TM_CLIBS', `TM_CDEPS', and other Makefile variables
- here; see `Makefile.in'.
-
- `gdb/tm-TTT.h'
- (`tm.h' is a link to this file, created by configure). Contains
- macro definitions about the target machine's registers, stack
- frame format and instructions. Crib from existing `tm-*.h' files
- when building a new one.
-
- `gdb/TTT-tdep.c'
- Contains any miscellaneous code required for this target machine.
- On some machines it doesn't exist at all. Sometimes the macros in
- `tm-TTT.h' become very complicated, so they are implemented as
- functions here instead, and the macro is simply defined to call
- the function.
-
- `gdb/exec.c'
- Defines functions for accessing files that are executable on the
- target system. These functions open and examine an exec file,
- extract data from one, write data to one, print information about
- one, etc. Now that executable files are handled with BFD, every
- target should be able to use the generic exec.c rather than its
- own custom code.
-
- `gdb/ARCH-pinsn.c'
- Prints (disassembles) the target machine's instructions. This file
- is usually shared with other target machines which use the same
- processor, which is why it is `ARCH-pinsn.c' rather than
- `TTT-pinsn.c'.
-
- `gdb/ARCH-opcode.h'
- Contains some large initialized data structures describing the
- target machine's instructions. This is a bit strange for a `.h'
- file, but it's OK since it is only included in one place.
- `ARCH-opcode.h' is shared between the debugger and the assembler,
- if the GNU assembler has been ported to the target machine.
-
- `gdb/tm-ARCH.h'
- This often exists to describe the basic layout of the target
- machine's processor chip (registers, stack, etc). If used, it is
- included by `tm-XXX.h'. It can be shared among many targets that
- use the same processor.
-
- `gdb/ARCH-tdep.c'
- Similarly, there are often common subroutines that are shared by
- all target machines that use this particular architecture.
-
- When adding support for a new target machine, there are various areas
- of support that might need change, or might be OK.
-
- If you are using an existing object file format (a.out or COFF),
- there is probably little to be done. See `bfd/doc/bfd.texinfo' for
- more information on writing new a.out or COFF versions.
-
- If you need to add a new object file format, you are beyond the scope
- of this document right now. Look at the structure of the a.out and
- COFF support, build a transfer vector (`xvec') for your new format, and
- start populating it with routines. Add it to the list in
- `bfd/targets.c'.
-
- If you are adding a new operating system for an existing CPU chip,
- add a `tm-XOS.h' file that describes the operating system facilities
- that are unusual (extra symbol table info; the breakpoint instruction
- needed; etc). Then write a `tm-XARCH-XOS.h' that just `#include's
- `tm-XARCH.h' and `tm-XOS.h'. (Now that we have three-part
- configuration names, this will probably get revised to separate the XOS
- configuration from the XARCH configuration.)
-
- File: gdbint.info, Node: Languages, Next: Releases, Prev: Target, Up: Top
-
- Adding a Source Language to GDB
- *******************************
-
- To add other languages to GDB's expression parser, follow the
- following steps:
-
- *Create the expression parser.*
- This should reside in a file `LANG-exp.y'. Routines for building
- parsed expressions into a `union exp_element' list are in
- `parse.c'.
-
- Since we can't depend upon everyone having Bison, and YACC produces
- parsers that define a bunch of global names, the following lines
- *must* be included at the top of the YACC parser, to prevent the
- various parsers from defining the same global names:
-
- #define yyparse LANG_parse
- #define yylex LANG_lex
- #define yyerror LANG_error
- #define yylval LANG_lval
- #define yychar LANG_char
- #define yydebug LANG_debug
- #define yypact LANG_pact
- #define yyr1 LANG_r1
- #define yyr2 LANG_r2
- #define yydef LANG_def
- #define yychk LANG_chk
- #define yypgo LANG_pgo
- #define yyact LANG_act
- #define yyexca LANG_exca
- #define yyerrflag LANG_errflag
- #define yynerrs LANG_nerrs
-
- At the bottom of your parser, define a `struct language_defn' and
- initialize it with the right values for your language. Define an
- `initialize_LANG' routine and have it call
- `add_language(LANG_language_defn)' to tell the rest of GDB that
- your language exists. You'll need some other supporting variables
- and functions, which will be used via pointers from your
- `LANG_language_defn'. See the declaration of `struct
- language_defn' in `language.h', and the other `*-exp.y' files, for
- more information.
-
- *Add any evaluation routines, if necessary*
- If you need new opcodes (that represent the operations of the
- language), add them to the enumerated type in `expression.h'. Add
- support code for these operations in `eval.c:evaluate_subexp()'.
- Add cases for new opcodes in two functions from `parse.c':
- `prefixify_subexp()' and `length_of_subexp()'. These compute the
- number of `exp_element's that a given operation takes up.
-
- *Update some existing code*
- Add an enumerated identifier for your language to the enumerated
- type `enum language' in `defs.h'.
-
- Update the routines in `language.c' so your language is included.
- These routines include type predicates and such, which (in some
- cases) are language dependent. If your language does not appear
- in the switch statement, an error is reported.
-
- Also included in `language.c' is the code that updates the variable
- `current_language', and the routines that translate the
- `language_LANG' enumerated identifier into a printable string.
-
- Update the function `_initialize_language' to include your
- language. This function picks the default language upon startup,
- so is dependent upon which languages that GDB is built for.
-
- Update `allocate_symtab' in `symfile.c' and/or symbol-reading code
- so that the language of each symtab (source file) is set properly.
- This is used to determine the language to use at each stack frame
- level. Currently, the language is set based upon the extension of
- the source file. If the language can be better inferred from the
- symbol information, please set the language of the symtab in the
- symbol-reading code.
-
- Add helper code to `expprint.c:print_subexp()' to handle any new
- expression opcodes you have added to `expression.h'. Also, add the
- printed representations of your operators to `op_print_tab'.
-
- *Add a place of call*
- Add a call to `LANG_parse()' and `LANG_error' in
- `parse.c:parse_exp_1()'.
-
- *Use macros to trim code*
- The user has the option of building GDB for some or all of the
- languages. If the user decides to build GDB for the language
- LANG, then every file dependent on `language.h' will have the
- macro `_LANG_LANG' defined in it. Use `#ifdef's to leave out
- large routines that the user won't need if he or she is not using
- your language.
-
- Note that you do not need to do this in your YACC parser, since if
- GDB is not build for LANG, then `LANG-exp.tab.o' (the compiled
- form of your parser) is not linked into GDB at all.
-
- See the file `configure.in' for how GDB is configured for different
- languages.
-
- *Edit `Makefile.in'*
- Add dependencies in `Makefile.in'. Make sure you update the macro
- variables such as `HFILES' and `OBJS', otherwise your code may not
- get linked in, or, worse yet, it may not get `tar'red into the
- distribution!
-
- File: gdbint.info, Node: Releases, Next: Partial Symbol Tables, Prev: Languages, Up: Top
-
- Configuring GDB for Release
- ***************************
-
- From the top level directory (containing `gdb', `bfd', `libiberty',
- and so on):
- make -f Makefile.in gdb.tar.Z
-
- This will properly configure, clean, rebuild any files that are
- distributed pre-built (e.g. `c-exp.tab.c' or `refcard.ps'), and will
- then make a tarfile. (If the top level directory has already beenn
- configured, you can just do `make gdb.tar.Z' instead.)
-
- This procedure requires:
- * symbolic links
-
- * `makeinfo' (texinfo2 level)
-
- * TeX
-
- * `dvips'
-
- * `yacc' or `bison'
-
- ... and the usual slew of utilities (`sed', `tar', etc.).
-
- TEMPORARY RELEASE PROCEDURE FOR DOCUMENTATION
- ---------------------------------------------
-
- `gdb.texinfo' is currently marked up using the texinfo-2 macros,
- which are not yet a default for anything (but we have to start using
- them sometime).
-
- For making paper, the only thing this implies is the right
- generation of `texinfo.tex' needs to be included in the distribution.
-
- For making info files, however, rather than duplicating the texinfo2
- distribution, generate `gdb-all.texinfo' locally, and include the files
- `gdb.info*' in the distribution. Note the plural; `makeinfo' will
- split the document into one overall file and five or so included files.
-
- File: gdbint.info, Node: Partial Symbol Tables, Next: BFD support for GDB, Prev: Releases, Up: Top
-
- Partial Symbol Tables
- *********************
-
- GDB has three types of symbol tables.
-
- * full symbol tables (symtabs). These contain the main information
- about symbols and addresses.
-
- * partial symbol tables (psymtabs). These contain enough
- information to know when to read the corresponding part of the
- full symbol table.
-
- * minimal symbol tables (msymtabs). These contain information
- gleaned from non-debugging symbols.
-
- This section describes partial symbol tables.
-
- A psymtab is constructed by doing a very quick pass over an
- executable file's debugging information. Small amounts of information
- are extracted -- enough to identify which parts of the symbol table will
- need to be re-read and fully digested later, when the user needs the
- information. The speed of this pass causes GDB to start up very
- quickly. Later, as the detailed rereading occurs, it occurs in small
- pieces, at various times, and the delay therefrom is mostly invisible to
- the user. (*Note Symbol Reading::.)
-
- The symbols that show up in a file's psymtab should be, roughly,
- those visible to the debugger's user when the program is not running
- code from that file. These include external symbols and types, static
- symbols and types, and enum values declared at file scope.
-
- The psymtab also contains the range of instruction addresses that the
- full symbol table would represent.
-
- The idea is that there are only two ways for the user (or much of
- the code in the debugger) to reference a symbol:
-
- * by its address (e.g. execution stops at some address which is
- inside a function in this file). The address will be noticed to
- be in the range of this psymtab, and the full symtab will be read
- in. `find_pc_function', `find_pc_line', and other `find_pc_...'
- functions handle this.
-
- * by its name (e.g. the user asks to print a variable, or set a
- breakpoint on a function). Global names and file-scope names will
- be found in the psymtab, which will cause the symtab to be pulled
- in. Local names will have to be qualified by a global name, or a
- file-scope name, in which case we will have already read in the
- symtab as we evaluated the qualifier. Or, a local symbol can be
- referenced when we are "in" a local scope, in which case the first
- case applies. `lookup_symbol' does most of the work here.
-
- The only reason that psymtabs exist is to cause a symtab to be read
- in at the right moment. Any symbol that can be elided from a psymtab,
- while still causing that to happen, should not appear in it. Since
- psymtabs don't have the idea of scope, you can't put local symbols in
- them anyway. Psymtabs don't have the idea of the type of a symbol,
- either, so types need not appear, unless they will be referenced by
- name.
-
- It is a bug for GDB to behave one way when only a psymtab has been
- read, and another way if the corresponding symtab has been read in.
- Such bugs are typically caused by a psymtab that does not contain all
- the visible symbols, or which has the wrong instruction address ranges.
-
- The psymtab for a particular section of a symbol-file (objfile)
- could be thrown away after the symtab has been read in. The symtab
- should always be searched before the psymtab, so the psymtab will never
- be used (in a bug-free environment). Currently, psymtabs are allocated
- on an obstack, and all the psymbols themselves are allocated in a pair
- of large arrays on an obstack, so there is little to be gained by
- trying to free them unless you want to do a lot more work.
-
- File: gdbint.info, Node: BFD support for GDB, Next: Symbol Reading, Prev: Partial Symbol Tables, Up: Top
-
- Binary File Descriptor Library Support for GDB
- **********************************************
-
- BFD provides support for GDB in several ways:
-
- *identifying executable and core files*
- BFD will identify a variety of file types, including a.out, coff,
- and several variants thereof, as well as several kinds of core
- files.
-
- *access to sections of files*
- BFD parses the file headers to determine the names, virtual
- addresses, sizes, and file locations of all the various named
- sections in files (such as the text section or the data section).
- GDB simply calls BFD to read or write section X at byte offset Y
- for length Z.
-
- *specialized core file support*
- BFD provides routines to determine the failing command name stored
- in a core file, the signal with which the program failed, and
- whether a core file matches (i.e. could be a core dump of) a
- particular executable file.
-
- *locating the symbol information*
- GDB uses an internal interface of BFD to determine where to find
- the symbol information in an executable file or symbol-file. GDB
- itself handles the reading of symbols, since BFD does not
- "understand" debug symbols, but GDB uses BFD's cached information
- to find the symbols, string table, etc.
-
- File: gdbint.info, Node: Symbol Reading, Next: Cleanups, Prev: BFD support for GDB, Up: Top
-
- Symbol Reading
- **************
-
- GDB reads symbols from "symbol files". The usual symbol file is the
- file containing the program which gdb is debugging. GDB can be directed
- to use a different file for symbols (with the "symbol-file" command),
- and it can also read more symbols via the "add-file" and "load"
- commands, or while reading symbols from shared libraries.
-
- Symbol files are initially opened by `symfile.c' using the BFD
- library. BFD identifies the type of the file by examining its header.
- `symfile_init' then uses this identification to locate a set of
- symbol-reading functions.
-
- Symbol reading modules identify themselves to GDB by calling
- `add_symtab_fns' during their module initialization. The argument to
- `add_symtab_fns' is a `struct sym_fns' which contains the name (or name
- prefix) of the symbol format, the length of the prefix, and pointers to
- four functions. These functions are called at various times to process
- symbol-files whose identification matches the specified prefix.
-
- The functions supplied by each module are:
-
- `XXX_symfile_init(struct sym_fns *sf)'
- Called from `symbol_file_add' when we are about to read a new
- symbol file. This function should clean up any internal state
- (possibly resulting from half-read previous files, for example)
- and prepare to read a new symbol file. Note that the symbol file
- which we are reading might be a new "main" symbol file, or might
- be a secondary symbol file whose symbols are being added to the
- existing symbol table.
-
- The argument to `XXX_symfile_init' is a newly allocated `struct
- sym_fns' whose `bfd' field contains the BFD for the new symbol
- file being read. Its `private' field has been zeroed, and can be
- modified as desired. Typically, a struct of private information
- will be `malloc''d, and a pointer to it will be placed in the
- `private' field.
-
- There is no result from `XXX_symfile_init', but it can call
- `error' if it detects an unavoidable problem.
-
- `XXX_new_init()'
- Called from `symbol_file_add' when discarding existing symbols.
- This function need only handle the symbol-reading module's
- internal state; the symbol table data structures visible to the
- rest of GDB will be discarded by `symbol_file_add'. It has no
- arguments and no result. It may be called after
- `XXX_symfile_init', if a new symbol table is being read, or may be
- called alone if all symbols are simply being discarded.
-
- `XXX_symfile_read(struct sym_fns *sf, CORE_ADDR addr, int mainline)'
- Called from `symbol_file_add' to actually read the symbols from a
- symbol-file into a set of psymtabs or symtabs.
-
- `sf' points to the struct sym_fns originally passed to
- `XXX_sym_init' for possible initialization. `addr' is the offset
- between the file's specified start address and its true address in
- memory. `mainline' is 1 if this is the main symbol table being
- read, and 0 if a secondary symbol file (e.g. shared library or
- dynamically loaded file) is being read.
-
- In addition, if a symbol-reading module creates psymtabs when
- XXX_symfile_read is called, these psymtabs will contain a pointer to a
- function `XXX_psymtab_to_symtab', which can be called from any point in
- the GDB symbol-handling code.
-
- `XXX_psymtab_to_symtab (struct partial_symtab *pst)'
- Called from `psymtab_to_symtab' (or the PSYMTAB_TO_SYMTAB macro)
- if the psymtab has not already been read in and had its
- `pst->symtab' pointer set. The argument is the psymtab to be
- fleshed-out into a symtab. Upon return, pst->readin should have
- been set to 1, and pst->symtab should contain a pointer to the new
- corresponding symtab, or zero if there were no symbols in that
- part of the symbol file.
-
- File: gdbint.info, Node: Cleanups, Next: Wrapping, Prev: Symbol Reading, Up: Top
-
- Cleanups
- ********
-
- Cleanups are a structured way to deal with things that need to be
- done later. When your code does something (like `malloc' some memory,
- or open a file) that needs to be undone later (e.g. free the memory or
- close the file), it can make a cleanup. The cleanup will be done at
- some future point: when the command is finished, when an error occurs,
- or when your code decides it's time to do cleanups.
-
- You can also discard cleanups, that is, throw them away without doing
- what they say. This is only done if you ask that it be done.
-
- Syntax:
-
- `OLD_CHAIN = make_cleanup (FUNCTION, ARG);'
- Make a cleanup which will cause FUNCTION to be called with ARG (a
- `char *') later. The result, OLD_CHAIN, is a handle that can be
- passed to `do_cleanups' or `discard_cleanups' later. Unless you
- are going to call `do_cleanups' or `discard_cleanups' yourself,
- you can ignore the result from `make_cleanup'.
-
- `do_cleanups (OLD_CHAIN);'
- Perform all cleanups done since `make_cleanup' returned OLD_CHAIN.
- E.g.:
- make_cleanup (a, 0);
- old = make_cleanup (b, 0);
- do_cleanups (old);
-
- will call `b()' but will not call `a()'. The cleanup that calls
- `a()' will remain in the cleanup chain, and will be done later
- unless otherwise discarded.
-
- `discard_cleanups (OLD_CHAIN);'
- Same as `do_cleanups' except that it just removes the cleanups
- from the chain and does not call the specified functions.
-
- Some functions, e.g. `fputs_filtered()' or `error()', specify that
- they "should not be called when cleanups are not in place". This means
- that any actions you need to reverse in the case of an error or
- interruption must be on the cleanup chain before you call these
- functions, since they might never return to your code (they `longjmp'
- instead).
-
- File: gdbint.info, Node: Wrapping, Next: Frames, Prev: Cleanups, Up: Top
-
- Wrapping Output Lines
- *********************
-
- Output that goes through `printf_filtered' or `fputs_filtered' or
- `fputs_demangled' needs only to have calls to `wrap_here' added in
- places that would be good breaking points. The utility routines will
- take care of actually wrapping if the line width is exceeded.
-
- The argument to `wrap_here' is an indentation string which is printed
- *only* if the line breaks there. This argument is saved away and used
- later. It must remain valid until the next call to `wrap_here' or
- until a newline has been printed through the `*_filtered' functions.
- Don't pass in a local variable and then return!
-
- It is usually best to call `wrap_here()' after printing a comma or
- space. If you call it before printing a space, make sure that your
- indentation properly accounts for the leading space that will print if
- the line wraps there.
-
- Any function or set of functions that produce filtered output must
- finish by printing a newline, to flush the wrap buffer, before
- switching to unfiltered ("`printf'") output. Symbol reading routines
- that print warnings are a good example.
-
- File: gdbint.info, Node: Frames, Next: Coding Style, Prev: Wrapping, Up: Top
-
- Frames
- ******
-
- A frame is a construct that GDB uses to keep track of calling and
- called functions.
-
- `FRAME_FP'
- in the machine description has no meaning to the
- machine-independent part of GDB, except that it is used when
- setting up a new frame from scratch, as follows:
-
- create_new_frame (read_register (FP_REGNUM), read_pc ()));
-
- Other than that, all the meaning imparted to `FP_REGNUM' is
- imparted by the machine-dependent code. So, `FP_REGNUM' can have
- any value that is convenient for the code that creates new frames.
- (`create_new_frame' calls `INIT_EXTRA_FRAME_INFO' if it is
- defined; that is where you should use the `FP_REGNUM' value, if
- your frames are nonstandard.)
-
- `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.
-
- File: gdbint.info, Node: Coding Style, Next: Host Conditionals, Prev: Frames, Up: Top
-
- Coding Style
- ************
-
- GDB is generally written using the GNU coding standards, as
- described in `standards.texi', which you can get from the Free Software
- Foundation. There are some additional considerations for GDB
- maintainers that reflect the unique environment and style of GDB
- maintenance. If you follow these guidelines, GDB will be more
- consistent and easier to maintain.
-
- GDB's policy on the use of prototypes is that prototypes are used to
- *declare* functions but never to *define* them. Simple macros are used
- in the declarations, so that a non-ANSI compiler can compile GDB
- without trouble. The simple macro calls are used like this:
-
- extern int
- memory_remove_breakpoint PARAMS ((CORE_ADDR, char *));
-
- Note the double parentheses around the parameter types. This allows
- an arbitrary number of parameters to be described, without freaking out
- the C preprocessor. When the function has no parameters, it should be
- described like:
-
- void
- noprocess PARAMS ((void));
-
- The `PARAMS' macro expands to its argument in ANSI C, or to a simple
- `()' in traditional C.
-
- All external functions should have a `PARAMS' declaration in a
- header file that callers include. All static functions should have such
- a declaration near the top of their source file.
-
- We don't have a gcc option that will properly check that these rules
- have been followed, but it's GDB policy, and we periodically check it
- using the tools available (plus manual labor), and clean up any
- remnants.
-