@c ---------------------------------------------------------------------- @node edi_init, debugging @findex edi_init @subheading Syntax @example #include void edi_init (jmp_buf start_state); @end example @subheading Description This function is part of the DJGPP @dfn{debugging support}. It should be called after a call to @code{v2loadimage} (@pxref{v2loadimage}) which loads an executable program as a debuggee. @code{edi_init} then takes care of initializing the data structures which need to be set before the debugger can set breakpoints and run the debuggee. The argument @var{start_state} is usually set by a preceding call to @code{v2loadimage}. @subheading Portability @portability !ansi, !posix @subheading Example @example if (v2loadimage (exec_file, cmdline, start_state)) @{ printf ("Load failed for image %s\n", exec_file); exit (1); @} edi_init (start_state); @end example @c ---------------------------------------------------------------------- @node save_npx, debugging @findex save_npx @tindex NPXREG@r{ type} @tindex NPX@r{ type} @subheading Syntax @example #include extern NPX npx; void save_npx (void); @end example @subheading Description This function saves the state of the x87 numeric processor in the external variable @code{npx}. This variable is a structure defined as follows in the header @file{debug/dbgcom.h}: @example typedef struct @{ unsigned short sig0; unsigned short sig1; unsigned short sig2; unsigned short sig3; unsigned short exponent:15; unsigned short sign:1; @} NPXREG; typedef struct @{ unsigned long control; unsigned long status; unsigned long tag; unsigned long eip; unsigned long cs; unsigned long dataptr; unsigned long datasel; NPXREG reg[8]; long double st[8]; char st_valid[8]; long double mmx[8]; char in_mmx_mode; char top; @} NPX; @end example @code{save_npx} should be called immediately before @code{run_child} (@pxref{run_child}) is called to begin or resume the debugged program. To restore the x87 state when control is returned to the debugger, call @code{load_npx}, see @ref{load_npx}. @subheading Portability @portability !ansi, !posix @subheading Example @example save_npx (); run_child (); load_npx (); @end example @c ---------------------------------------------------------------------- @node load_npx, debugging @findex load_npx @subheading Syntax @example #include extern NPX npx; void load_npx (void); @end example @subheading Description This function restores the state of the x87 numeric processor from the data saved in the external variable @code{npx}. This variable is a structure defined as follows in the header @file{debug/dbgcom.h}: @example typedef struct @{ unsigned short sig0; unsigned short sig1; unsigned short sig2; unsigned short sig3; unsigned short exponent:15; unsigned short sign:1; @} NPXREG; typedef struct @{ unsigned long control; unsigned long status; unsigned long tag; unsigned long eip; unsigned long cs; unsigned long dataptr; unsigned long datasel; NPXREG reg[8]; long double st[8]; char st_valid[8]; long double mmx[8]; char in_mmx_mode; char top; @} NPX; @end example @code{load_npx} should be called immediately after @code{run_child} (@pxref{run_child}) is called to begin or resume the debugged program, and provided that a call to @code{save_npx} was issued before @code{run_child} was called. @xref{save_npx}. @subheading Portability @portability !ansi, !posix @subheading Example @example save_npx (); run_child (); load_npx (); @end example @c ---------------------------------------------------------------------- @node run_child, debugging @findex run_child @tindex TSS@r{ structure} @tindex TSS@r{ type} @subheading Syntax @example #include void run_child (void); @end example @subheading Description This function starts or resumes the debugged program, via a @code{longjmp} to the debuggee's code. When the debuggee hits a breakpoint, or exits normally, the exception handler that is called to service the breakpoint exception will @code{longjmp} back to @code{run_child}, and it will then return to the caller. After @code{run_child} returns, the debugger usually examines the @code{a_tss} variable to find out the reason the debuggee stopped. The @code{a_tss} variable is defined by the header @file{debug/tss.h} as follows: @example typedef struct TSS @{ unsigned short tss_back_link; unsigned short res0; unsigned long tss_esp0; unsigned short tss_ss0; unsigned short res1; unsigned long tss_esp1; unsigned short tss_ss1; unsigned short res2; unsigned long tss_esp2; unsigned short tss_ss2; unsigned short res3; unsigned long tss_cr3; unsigned long tss_eip; unsigned long tss_eflags; unsigned long tss_eax; unsigned long tss_ecx; unsigned long tss_edx; unsigned long tss_ebx; unsigned long tss_esp; unsigned long tss_ebp; unsigned long tss_esi; unsigned long tss_edi; unsigned short tss_es; unsigned short res4; unsigned short tss_cs; unsigned short res5; unsigned short tss_ss; unsigned short res6; unsigned short tss_ds; unsigned short res7; unsigned short tss_fs; unsigned short res8; unsigned short tss_gs; unsigned short res9; unsigned short tss_ldt; unsigned short res10; unsigned short tss_trap; unsigned char tss_iomap; unsigned char tss_irqn; unsigned long tss_error; @} TSS; extern TSS a_tss; @end example See the example below for a typical tests after @code{run_child} returns. Note that, generally, you'd need to save the standard handles before calling @code{run_child} and restore them after it returns. Otherwise, if the debuggee redirects one of its standard handles, the corresponding debugger's standard handle is redirected as well. @xref{redir_to_child}, and see @ref{redir_to_debugger}. @subheading Portability @portability !ansi, !posix @subheading Example @example save_npx (); run_child (); load_npx (); if (a_tss.tss_irqn == 0x21) @{ status = DEBUGGEE_EXITED; exit_code = a_tss.tss_eax & 0xff; @} else @{ status = DEBUGGEE_GOT_SIGNAL if (a_tss.tss_irqn == 0x75) signal_number = SIGINT; else if (a_tss.tss_irqn == 1 || a_tss.tss_irqn == 3) signal_number = SIGTRAP; /* a breakpoint */ @} @end example @c ---------------------------------------------------------------------- @node read_child, debugging @findex read_child @subheading Syntax @example #include void read_child (unsigned child_addr, void *buf, unsigned len); @end example @subheading Description This function reads the memory of the debugged process starting at address @var{child_addr} for @var{len} bytes, and copies the data read to the buffer pointed to by @var{buf}. It is used primarily to save the original instruction at the point where a breakpoint instruction is inserted (to trigger a trap when the debuggee's code gets to that point). @xref{write_child}. @subheading Return Value The function return zero if it has successfully transferred the data, non-zero otherwise (e.g., if the address in @var{child_addr} is outside the limits of the debuggee's code segment. @subheading Portability @portability !ansi, !posix @c ---------------------------------------------------------------------- @node write_child, debugging @findex write_child @subheading Syntax @example #include void write_child (unsigned child_addr, void *buf, unsigned len); @end example @subheading Description This function transfers @var{len} bytes from the buffer pointed to by @var{buf} in the debugger's data segment to the memory of the debugged process starting at the address @var{child_addr}. It is used primarily to insert a breakpoint instruction into the debugged process (to trigger a trap when the debuggee's code gets to that point). The companion function @code{read_child} (@pxref{read_child}) is usually called before @code{write_child} to save the original code overwritten by the breakpoint instruction. @subheading Return Value The function return zero if it has successfully transferred the data, non-zero otherwise (e.g., if the address in @var{child_addr} is outside the limits of the debuggee's code segment. @subheading Portability @portability !ansi, !posix @c ---------------------------------------------------------------------- @node read_sel_addr, debugging @findex read_sel_addr @subheading Syntax @example #include void read_sel_addr (unsigned offset, void *buf, unsigned len, unsigned sel); @end example @subheading Description This function reads the memory starting at offset @var{offset} in selector @var{sel} for @var{len} bytes, and copies the data read to the buffer pointed to by @var{buf}. @xref{write_sel_addr}. @subheading Return Value The function return zero if it has successfully transferred the data, non-zero otherwise (e.g., if the address in @var{offset} is outside the limits of the segment whose selector is @var{sel}). @subheading Portability @portability !ansi, !posix @c ---------------------------------------------------------------------- @node write_sel_addr, debugging @findex write_sel_addr @subheading Syntax @example #include void write_sel_addr (unsigned sel, unsigned offset, void *buf, unsigned len); @end example @subheading Description This function transfers @var{len} bytes from the buffer pointed to by @var{buf} in the data segment whose selector is @var{sel}, at offset @var{offset}. The companion function @code{read_sel_addr} (@pxref{read_sel_addr}) is usually called before @code{write_sel_addr} to save the original contents, if needed. @subheading Return Value The function return zero if it has successfully transferred the data, non-zero otherwise (e.g., if the address in @var{offset} is outside the limits of the @var{sel}s segment). @subheading Portability @portability !ansi, !posix @c ---------------------------------------------------------------------- @node cleanup_client, debugging @findex cleanup_client @subheading Syntax @example #include void cleanup_client (void); @end example @subheading Description This function is typically called when the debugged process exits or is aborted. It restores segment descriptors, closes file handles that were left open by the debuggee, frees protected-mode and conventional memory and any segment descriptors allocated by the debuggee, and restores the debugger's original signal handlers. @subheading Portability @portability !ansi, !posix @c ---------------------------------------------------------------------- @node v2loadimage, debugging @findex v2loadimage @subheading Syntax @example #include int v2loadimage (const char *program, const char *cmdline, jmp_buf load_state); @end example @subheading Description This function loads an executable image of a DJGPP v2.x program and prepares it for debugging. @var{program} should point to the file name of the executable program. @code{v2loadimage} does @strong{not} search the @code{PATH} and does @strong{not} try any executable extensions, so @var{program} should point to a fully-qualified path, complete with the drive, directory, and file-name extension; otherwise the call will fail. @var{cmdline} should point to the command-line arguments to be passed to the program. A command line up to 126 characters long can be formatted exactly like the command tail DOS passes to programs: the first byte gives the length of the command tail, the tail itself begins with the second byte, and the tail is terminated by a CR character (decimal code 13); the length byte does not include the CR. Longer command lines require a different format: the first byte is 255, the command-line starting with the second byte which is terminated by a NUL character (decimal code 0). Regardless of the method used, the command-line arguments should look as if they were to be passed to the library function @code{system}. In particular, all special characters like wildcards and whitespace should be quoted as if they were typed at the DOS prompt. After the function loads the image and sets up the necessary memory segments for it to be able to run, it sets @var{load_state} so that it can be used to @code{longjmp} to the debuggee's entry point. This information is typically used by @code{run_child} (@pxref{run_child}). @subheading Return Value Zero in case of success, non-zero otherwise. @subheading Portability @portability !ansi, !posix @subheading Example @example cmdline = (char *) alloca (strlen (args) + 4); cmdline[0] = strlen (args); strcpy (cmdline + 1, args); cmdline[strlen (args) + 1] = 13; if (v2loadimage (exec_file, cmdline, start_state)) @{ printf ("Load failed for image %s\n", exec_file); exit (1); @} edi_init (start_state); @end example @c ---------------------------------------------------------------------- @node wild, debugging @findex wild @subheading Syntax @example #include int wild (char *pattern, char *string); @end example @subheading Description This function matches a string pointed to by @var{string} against a pattern pointed to by @var{pattern}. @var{pattern} may include wildcard characters @samp{?} and @samp{*}, meaning, respectively, any single character and any string of characters. The function returns non-zero if the string matches the pattern, zero otherwise. This function is meant to be used for simple matching of patterns, such as if a debugger needs to allow specification of symbols using wildcards. @subheading Return Value The function returns non-zero if the string matches the pattern, zero otherwise. @subheading Portability @portability !ansi, !posix @c ---------------------------------------------------------------------- @node redir_debug_init, debugging @findex redir_debug_init @tindex dbg_redirect@r{ structure} @tindex cmdline_t@r{ type} @subheading Syntax @example #include int redir_debug_init (cmdline_t *cmd); @end example @subheading Description This function initializes the data structure in the @var{cmd} variable required to save and restore debugger's standard handles across invocations of @code{run_child} (@pxref{run_child}). The debugger will then typically call @code{redir_to_child} and @code{redir_to_debugger}. These functions are needed when a debugger wants to redirect standard handles of the debuggee, or if the debuggee redirects some of its standard handles, because the debuggee is not a separate process, we just pretend it is by jumping between two threads of execution. But, as far as DOS is concerned, the debugger and the debuggee are a single process, and they share the same @dfn{Job File Table} (JFT). The JFT is a table maintained by DOS in the program's PSP where, for each open handle, DOS stores the index into the SFT, the @dfn{System File Table}. (The SFT is an internal data structure where DOS maintains everything it knows about a certain open file/device.) A handle that is returned by @code{open}, @code{_open} and other similar functions is simply an index into the JFT where DOS stored the SFT entry index for the file or device that the program opened. When a program starts, the first 5 entries in the JFT are preconnected to the standard devices. Any additional handles opened by either the debugger or the debuggee use handles beyond the first 5 (unless one of the preconnected handles is deliberately closed). Here we mostly deal with handles 0, 1 and 2, the standard input, standard output, and standard error; they all start connected to the console device (unless somebody redirects the debugger's I/O from the command line). Since both the debugger and the debuggee share the same JFT, their handles 0, 1 and 2 point to the same JFT entries and thus are connected to the same files/devices. Therefore, if the debugger redirects its standard output, the standard output of the debuggee is also automagically redirected to the same file/device! Similarly, if the debuggee redirects its stdout to a file, you won't be able to see debugger's output (it will go to the same file where the debuggee has its output); and if the debuggee closes its standard input, you will lose the ability to talk to debugger! The debugger redirection support attempts to solve all these problems by creating an illusion of two separate sets of standard handles. Each time the debuggee is about to be run or resumed, it should call @code{redir_to_child} to redirect debugger's own standard handles to the file specified in the command-line (as given by e.g. the "run" command of GDB) before running the debuggee, then call @code{redir_to_debugger} to redirect them back to the debugger's original input/output when the control is returned from the debuggee (e.g. after a breakpoint is hit). Although the debugger and the debuggee have two separate copies of the file-associated data structures, the debugger still can redirect standard handles of the debuggee because they use the same JFT entries as debugger's own standard handles. The @code{cmdline_t} structure is declared in the header @file{debug/redir.h} as follows: @example struct dbg_redirect @{ int inf_handle; /* debuggee's handle */ int our_handle; /* debugger's handle */ char *file_name; /* file name where debuggee's handle is * redirected */ int mode; /* mode used to open() the above file */ off_t filepos; /* file position of debuggee's handle; unused */ @}; typedef struct _cmdline @{ char *command; /* command line with redirection removed */ int redirected; /* 1 if handles redirected for child */ struct dbg_redirect **redirection;/* info about redirected handles */ @} cmdline_t; @end example In the @code{cmdline_t} structure, the @code{redirection} member points to an array of 3 @code{dbg_redirect} structures, one each for each one of the 3 standard handles. The @code{inf_handle} and @code{our_handle} members of those structures are used to save the handle used, respectively, by the debuggee (a.k.a.@: @dfn{the inferior process}) and by the debugger. The @var{cmd} variable is supposed to be defined by the debugger's application code. @code{redir_debug_init} is called to initialize that variable. It calls @code{redir_cmdline_delete} to close any open handles held in @var{cmd} and to free any allocated storage; then it fills @var{cmd} with the trivial information (i.e., every standard stream is connected to the usual handles 0, 1, and 2). @subheading Return Value @code{redir_debug_init} returns zero in case of success, or -1 otherwise. @subheading Portability @portability !ansi, !posix @subheading Example @example if (redir_debug_init (&child_cmd) == -1) fatal ("Cannot allocate redirection storage: not enough memory.\n"); @end example @c ---------------------------------------------------------------------- @node redir_cmdline_delete, debugging @findex redir_cmdline_delete @subheading Syntax @example #include void redir_cmdline_delete (cmdline_t *cmd); @end example @subheading Description For the rationale and general description of the debugger redirection issue, see @ref{redir_debug_init}. This function serves as a destructor for a @code{cmdline_t} object. It frees storage used for the command-line arguments associated with @var{cmd}, closes any open handles stored in it, and frees memory used to store the file handles and the file names of the files where standard handles were redirected. The function is safe to use even if @var{cmd} might be a @code{NULL} pointer, or if some of members of the @code{cmdline_t} structure are @code{NULL} pointers. @xref{redir_debug_init}, for detailed description of the @code{cmdline_t} structure. @subheading Portability @portability !ansi, !posix @subheading Example @example redir_cmdline_delete (&child_cmd); @end example @c ---------------------------------------------------------------------- @node redir_cmdline_parse, debugging @findex redir_cmdline_parse @subheading Syntax @example #include int redir_cmdline_parse (const char *args, cmdline_t *cmd); @end example @subheading Description For the rationale and general description of the debugger redirection issue, see @ref{redir_debug_init}. This function parses a command-line tail (i.e., without the program to be invoked) passed as a string in @var{args}. For every redirection directive in @var{args}, like @samp{>> foo}, it opens the file that is the target of the redirection, and records in @var{cmd} the information about these redirections. (@xref{redir_debug_init}, for details of the @code{cmdline_t} structure that is used to hold this information.) The command line with redirections removed is placed into @code{cmd->command} (typically, it will be used to call @code{v2loadimage}, @pxref{v2loadimage}), while the rest of information is used by @code{redir_to_child} and @code{redir_to_debugger} to redirect standard handles before and after calling @code{run_child}. @subheading Return Value The function returns zero in case of success, -1 otherwise. Failure usually means some kind of syntax error, like @samp{>} without a file name following it; or a file name that isn't allowed by the underlying OS, like @file{lost+found} on DOS. @subheading Portability @portability !ansi, !posix @subheading Example @example /* Init command line storage. */ if (redir_debug_init (&child_cmd) == -1) fatal ("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 = strdup (args); cmdline = (char *) alloca (strlen (args) + 4); cmdline[0] = strlen (args); strcpy (cmdline + 1, args); cmdline[strlen (args) + 1] = 13; if (v2loadimage (exec_file, cmdline, start_state)) @{ printf ("Load failed for image %s\n", exec_file); exit (1); @} @end example @c ---------------------------------------------------------------------- @node redir_to_child, debugging @findex redir_to_child @subheading Syntax @example #include int redir_to_child (cmdline_t *cmd); @end example @subheading Description For the rationale and general description of the debugger redirection issue, see @ref{redir_debug_init}. This function redirects all 3 standard streams so that they point to the files/devices where the child (a.k.a.@: debuggee) process connected them. All three standard handles point to the console device by default, but this could be changed, either because the command line for the child requested redirection, like in @samp{prog > foo}, or because the child program itself redirected one of its standard handles e.g. with a call to @code{dup2}. @code{redir_to_child} uses information stored in the @code{cmdline_t} variable pointed to by the @var{cmd} argument to redirect the standard streams as appropriate for the debuggee, while saving the original debugger's handles to be restored by @code{redir_to_debugger}. @subheading Return Value The function returns zero in case of success, -1 in case of failure. Failure usually means the process has run out of available file handles. @subheading Portability @portability !ansi, !posix @subheading Example @example errno = 0; if (redir_to_child (&child_cmd) == -1) @{ redir_to_debugger (&child_cmd); error ("Cannot redirect standard handles for program: %s.", strerror (errno)); @} @end example @c ---------------------------------------------------------------------- @node redir_to_debugger, debugging @findex redir_to_debugger @subheading Syntax @example #include int redir_to_debugger (cmdline_t *cmd); @end example @subheading Description For the rationale and general description of the debugger redirection issue, see @ref{redir_debug_init}. This function redirects all 3 standard streams so that they point to the files/devices where the debugger process connected them. All three standard handles point to the console device by default, but this could be changed, either because the command line for the child requested redirection, like in @samp{prog > foo}, or because the child program itself redirected one of its standard handles e.g. with a call to @code{dup2}. @code{redir_to_debugger} uses information stored in the @code{cmdline_t} variable pointed to by the @var{cmd} argument to redirect the standard streams as appropriate for the debugger, while saving the original debuggee's handles to be restored by @code{redir_to_child}. @subheading Return Value The function returns zero in case of success, -1 in case of failure. Failure usually means the process has run out of available file handles. @subheading Portability @portability !ansi, !posix @subheading Example @example /* Restore debugger's standard handles. */ errno = 0; if (redir_to_debugger (&child_cmd) == -1) error ("Cannot redirect standard handles for debugger: %s.", strerror (errno)); @end example @c ---------------------------------------------------------------------- @node syms_init, debugging @findex syms_init @subheading Syntax @example #include void syms_init (char *file); @end example @subheading Description This function reads debugging symbols from the named @var{file}, which should be an executable program (either a @file{.exe} file or a raw COFF image created by @file{ld.exe}, the linker). It then processes the symbols: classifies them by type, sorts them by name and value, and stores them in internal data structures used by other symbol-related functions, such as @code{syms_val2name}, @code{syms_val2line}, etc. You @strong{must} call @code{syms_init} before calling the other @code{syms_*} functions. Currently, @code{syms_init} only supports COFF and AOUT debugging format, so programs compiled with @samp{-gstabs} cannot be processed by it. @subheading Return Value None. @portability !ansi, !posix @subheading Example @example syms_init("c:/foo/bar/baz.exe"); @end example @c ---------------------------------------------------------------------- @node syms_name2val, debugging @findex syms_name2val @subheading Syntax @example #include extern int undefined_symbol; extern int syms_printwhy; unsigned long syms_name2val (const char *string); @end example @subheading Description This function returns the address of a symbol specified by @var{string}. @var{string} may be one of the following: @itemize @bullet @item A number, with or without a sign, in which case the number specifies the address or an offset from an address. @item A file name and a line number: @code{@var{file}#[@var{line}]}, where @var{file} is the name of one of the source files linked into the program whose symbols were read by @code{syms_init}, and @var{line} is a line number in that @var{file}. If @var{line} is omitted, it defaults to zero. Note that the COFF format supported by DJGPP only stores the basename of the source files, so do not specify @var{file} with leading directories. @item A symbol name as a string. The name can be specified either with or without the leading underscore @samp{_}. @item A register name @code{%@var{reg}}. @var{reg} specifies the value of one of the debuggee's registers saved in the external variable @code{a_tss} (@pxref{run_child}). @item Any sensible combination of the above elements, see the example below. @end itemize @code{syms_name2val} looks up the specified file, line, and symbol in the symbol table prepared by @code{syms_init}, finds their addresses, adds the offset, if any, and returns the result. If the specified file, line, or symbol cannot be found, @code{syms_name2val} returns zero and sets the global variable @code{undefined_symbol} to a non-zero value. If the global variable @code{syms_printwhy} is non-zero, an error message is printed telling which part of the argument @var{string} was invalid. You must call @code{syms_init} (@pxref{syms_init}) before calling any of the other @code{syms_*} functions for the first time. @subheading Return Value The address specified by @var{string}, or zero, if none found. @subheading Portability @portability !ansi, !posix @subheading Example @example unsigned long addr1, addr2, addr3; syms_init ("foo.exe"); addr1 = syms_name2val ("foo.c#256+12"); addr2 = syms_name2val ("_main"); addr3 = syms_name2val ("struct_a_var+%eax+4"); @end example @c ---------------------------------------------------------------------- @node syms_val2name, debugging @findex syms_val2name @subheading Syntax @example #include char *syms_val2name (unsigned long addr, unsigned long *offset); @end example @subheading Description This function takes an address @var{addr} and returns the name of the closest symbol whose address is less that @var{addr}. If @var{offset} is not a @code{NULL} pointer, the offset of @var{addr} from the symbol's address is stored in the variable pointed to by @var{offset}. You must call @code{syms_init} (@pxref{syms_init}) before calling any of the other @code{syms_*} functions for the first time. This function is meant to be used to convert numerical addresses into function names and offsets into their code, like what @code{symify} does with the call frame traceback. The function ignores several dummy symbols, like @samp{_end} and @samp{_etext}. @subheading Return Value The name of the found symbol, or the printed hexadecimal representation of @var{addr}, if no symbol was found near @var{addr}. The return value is a pointer to a static buffer, so don't overwrite it and don't pass it to @code{free}! @subheading Portability @portability !ansi, !posix @subheading Example @example unsigned long offs; char *symbol_name; syms_init ("foo.exe"); symbol_name = syms_val2name (0x1c12, &offs); printf ("The address %x is at %s%+ld\n", 0x1c12, symbol_name, offs); @end example @c ---------------------------------------------------------------------- @node syms_val2line, debugging @findex syms_val2line @subheading Syntax @example #include char *syms_val2line (unsigned long addr, int *line, int exact); @end example @subheading Description This function takes an address @var{addr} and returns the source file name which correspond to that address. The line number in that source file is stored in the variable pointed by @var{line}. If @var{exact} is non-zero, the function succeeds only if @var{addr} is the first address which corresponds to some source line. You must call @code{syms_init} (@pxref{syms_init}) before calling any of the other @code{syms_*} functions for the first time. @subheading Return Value The name of the source file which corresponds to @var{addr}, or @code{NULL} if none was found. @subheading Portability @portability !ansi, !posix @subheading Example @example int lineno; char *file_name; syms_init ("foo.exe"); file_name = syms_val2line (0x1c12, &lineno); printf ("The address %x is on %s, line %d\n", 0x1c12, file_name, line); @end example @c ---------------------------------------------------------------------- @node syms_listwild, debugging @findex syms_listwild @subheading Syntax @example #include void syms_listwild (char *pattern, void (*handler) (unsigned long addr, char type_c, char *name, char *file, int lnum)); @end example @subheading Description This function walks through all the symbols that were read by a previous call to @code{syms_init} (@pxref{syms_init}). For each symbol whose name matches @var{pattern}, it invokes the user-defined function @var{handler}, passing it information about that symbol: @table @code @item address the address of the symbol. @item type_c a letter that specifies the type of the symbol, as follows: @table @samp @item T @itemx t ``text'', or code: usually a function. @item D @itemx d data: an initialized variable. @item B @itemx b ``bss'': an uninitialized variable. @item F @item f a function (in @code{a.out} file only). @item V @itemx v a set element or pointer (in @code{a.out} file only). @item I @itemx i an indirect symbol (in @code{a.out} file only). @item U @itemx u an undefined (a.k.a.@: unresolved) symbol. @item A @itemx a an absolute symbol. @end table @item name the name of the symbol. @item file the source file name where the symbol is defined. @item lnum the line number on which the symbol is defined in the source file. @end table Since variables and functions defined in C get prepended with an underscore @samp{_}, begin @var{pattern} with @samp{_} if you want it to match C symbols. You must call @code{syms_init} (@pxref{syms_init}) before calling any of the other @code{syms_*} functions for the first time. @subheading Return Value None. @subheading Portability @portability !ansi, !posix @subheading Example @example void print_sym (unsigned long addr, char type_c, char *name, char *file, int lnum) @{ printf (file ? "%s: %lx %c %s:%d\n" : "%s: %lx %c\n", name, addr, type_c, file ? file : "", lnum ); @} int main (void) @{ syms_init ("foo.exe"); /* List all the symbols which begin with "___djgpp". */ syms_listwild ("___djgpp*", print_sym); return 0; @} @end example @c ---------------------------------------------------------------------- @node syms_module, debugging @findex syms_module @subheading Syntax @example #include char *syms_module (int nfile); @end example @subheading Description This function returns the name of the source file (a.k.a.@: module) whose ordinal number in the symbol table is @var{nfile}. You must call @code{syms_init} (@pxref{syms_init}) before calling any of the other @code{syms_*} functions for the first time. @subheading Return Value The name of the source file, or a @code{NULL} pointer if @var{nfile} is negative or larger than the total number of modules linked into the program whose symbols were read by @code{syms_init}. @subheading Portability @portability !ansi, !posix @c ---------------------------------------------------------------------- @node syms_line2val, debugging @findex syms_line2val @subheading Syntax @example #include unsigned long syms_line2val (char *filename, int lnum); @end example @subheading Description This function returns the address of the first instruction produced from the line @var{lnum} of the source file @var{filename} that was linked into a program whose symbols were read by a previous call to @code{syms_init}. COFF debugging format does not support pathnames, so @var{filename} should not include leading directories, just the basename. You must call @code{syms_init} (@pxref{syms_init}) before calling any of the other @code{syms_*} functions for the first time. @subheading Return Value The address of the first instruction produced from the line, or zero if @var{filename} is not found in the symbol table or if no executable code was generated for line @var{lnum} in @var{filename}. @subheading Portability @portability !ansi, !posix @subheading Example @example syms_init ("foo.exe"); printf ("Line 3 of foo.c is at address %lx\n", syms_line2val("foo.c", 3)); @end example