Index of Topics
- - C -
- CLIAlloc
CLIFree
CLIReloc
CLISeek
CLITell
CLIWrite
- D -
- Data Types
Debugging Information
DWAddBitField
DWAddEnumerationConstant
DWAddField
DWAddFriend
DWAddInheritance
DWAddress
DWArrayDimension
DWBeginArray
DWBeginCommonBlock
DWBeginCompileUnit
DWBeginEnumeration
DWBeginInlineSubroutine
DWBeginLexicalBlock
DWBeginStruct
DWBeginSubroutine
DWBeginSubroutineType
DWConstant
DWDeclFile
DWDeclPos
DWEllipsis
DWEndArray
DWEndCommonBlock
DWEndCompileUnit
DWEndEnumeration
DWEndLexicalBlock
DWEndStruct
DWEndSubroutine
DWEndSubroutineType
DWFini
DWFormalParameter
DWFundamental
DWIncludeCommonBlock
DWInit
DWLabel
DWLineNum
DWListEntry
DWListFini
DWListInit
DWLocConstS
DWLocConstU
DWLocFini
DWLocInit
DWLocNewLabel
DWLocOp
DWLocOp0
DWLocReg
DWLocSegment
DWLocSetLabel
DWLocStatic
DWLocTrash
DWMacDef
DWMacEndFile
DWMacFini
DWMacParam
DWMacStartFile
DWMacUnDef
DWMacUse
DWMemberPointer
DWModifier
DWPointer
DWPubname
DWReference
DWSetFile
DWString
DWStruct
DWTypedef
DWVariable
- E -
- Examples
- I -
- Initialization and Finalization
- L -
- Location Expression Routines
- O -
- Ordering Considerations
- P -
- Performance Considerations
- R -
- Required Client Routines
Revision History
- S -
- Subroutine Type Declarations
- T -
- Typing Information
The include file "dw.h" should be included to access the DW library.
Data Types
The following types are defined in "dwcnf.h" and may be redefined if the entire library is to be recompiled
("dw.h" automatically includes "dwcnf.h").
- Type
- Description
dw_sym_handle
- Has a client defined meaning; the DW library will pass these back to the client in CLIRelocs for DW_W_STATIC
, and DW_W_SEGMENT.
dw_targ_addr
- The contents of dw_targ_addr is unimportant to the DW library; it is only used for sizeof( dw_targ_addr ).
A dw_targ_addr is the type that will be emitted for relocations to run-time addresses.
dw_targ_seg
- This is the size of the quantity that DW_W_SEGMENT emits.
dw_addr_offset
- The type used for offsets from some base address. For example, the start_scope parameter to typing routines,
or the addr parameter to line number information. The code assumes this is an unsigned integer type.
dw_addr_delta
- An integer type that can hold the largest possible difference between the addr parameter for two subsequent calls
to DWLineNum.
dw_linenum
- A line number. It must be an unsigned integer type.
dw_linenum_delta
- dw_linenum_delta is a type that can hold the largest possible difference between two adjacent line numbers passed to DWLineNum
or DWReference.
dw_column
- A column number. It must be an unsigned integer type.
dw_column_delta
- Type that can hold the largest possible difference between two adjacent column numbers passed to DWReference.
dw_size_t
- Used for sizes of various things such as block constants (i.e. for DWAddEnumerationConstant) and the size parameter
to CLIWrite.
dw_uconst
- An unsigned integer type that can hold the largest possible unsigned integer constant.
dw_sconst
- A signed integer type that can hold the largest possible signed integer constant.
dw_sectnum
- Enumerated type that can hold all defined Dwarf sections, passed to client functions
dw_out_offset
- A integer type that can hold the largest possible section offset passed to CLISeek and returned by CLITell
dw_reloc_type
- A integer type that can hold the all relocation type
Initialization and Finalization
In the following functions, unless specified otherwise all strings are assumed to be null-terminated.
The DW library does not assume that a pointer passed to it is valid beyond the function call used to pass it.
For example, you can pass the address of an auto-buffer that contains a string.
All names passed to the DW library should be unmangled.
The cli parameter required for all DW functions except DWInit is assumed to be a valid value returned
by a call to DWInit.
Currently DWENTRY is defined to be nothing. It was created in case there is ever a need to put the DW library
into a DLL.
DWInit
dw_client DWENTRY DWInit( dw_init_info *info );
Initialization for a compilation unit. Return an unique client id. This function will call client functions
passed to it, so any client function initialization must be done before the call to DWInit.
typedef struct {
void (*reloc)(
dw_sectnum, uint, ... );
void (*write)(
dw_sectnum, const void *, dw_size_t );
void (*seek)(
dw_sectnum, dw_out_offset, int );
dw_out_offset (*tell)( dw_sectnum );
void *(*alloc)(
size_t );
void (*free)(
void * );
} dw_funcs;
typedef struct {
dw_lang language;
uint_8 compiler_options;
const char *producer_name;
jmp_buf exception_handler;
dw_funcs funcs;
} dw_init_info;
- Member
- Description
language
- Language used.
- Constant
- Language
DWLANG_C
- ISO/ANSI C
DWLANG_CPP
- C++
DWLANG_FORTRAN
- FORTRAN77
compile_options
- Compilation option, which is a combination of bits:
- Bit
- Description
DW_CM_BROWSER
- The library generates the debugging information for the class browser.
DW_CM_DEBUGGER
- The library generates the debugging information for the debugger.
DW_CM_UPPER
- For FORTRAN - The compiler converts all identifier names to upper case.
DW_CM_LOWER
- For FORTRAN - The compiler converts all identifier names to lower case.
producer
- A string that identifies the compiler.
exception_handler
- If the library ends up in a situation which it can't handle (can we say bug ;-) ) this jmp_buf will be called with a non-zero
value. This is a fatal exit, and the client should not call any of the DW functions.
FIXME: The library is currently not very good at cleaning up memory in these situations.
funcs
- These functions are described in a later section. The initialization routines may call any of them; so any initialization
necessary for these routines must be done before DWInit is called.
The details of the above functions are discussed in Part 3.
DWFini
void DWENTRY DWFini( dw_client cli );
Finalize the debugging information generator. This routine must be called last. It frees any structures
that the DW library required, and flushes all the debugging information.
DWBeginCompileUnit
dw_handle DWENTRY DWBeginCompileUnit( dw_client cli, const char *source_filename, const char *directory, dw_loc_handle
segment, const unsigned offset_size );
This function is called some time after DWInit. The only other DW functions that can be called in between
are those dealing with location expressions.
- Parameter
-
source_filename
- Name of the source file.
directory
- Compilation directory.
segment
- A location expression who's result is the code segment portion of the low_pc and high_pc.
offset_size
- The size in bytes of the offset portion of an address in this compile unit
The following CLIRelocs will be required:
- DW_W_HIGH_PC
-
DW_W_LOW_PC
-
DW_W_SECTION_POS
-
DW_W_UNIT_SIZE
-
DWEndCompileUnit
void DWENTRY DWEndCompileUnit( dw_client cli );
This function pairs up with DWBeginCompileUnit. After this, until the next DWBeginCompileUnit
, the only valid calls are those made to location expression routines (or DWFini ).
Ordering Considerations
In general the DW routines are called in an order that matches the order of the declarations during the source program.
The sole exception to this are the Macro information routines. Since it is possible to have a separate preprocessor
pass, the library assumes that these routines can be called before any of the other routines. That is why the macro
routines have a separate mechanism for specifying file and line number.
DWMacStartFile
void DWENTRY DWMacStartFile( dw_client cli, dw_linenum line, const char *name );
Subsequent DWMac calls refer to the named file.
DWMacEndFile
void DWENTRY DWMacEndFile( dw_client cli );
End the current included file.
DWMacDef
dw_macro DWENTRY DWMacDef( dw_client cli, dw_linenum line, const char *name );
Defines a macro. name is the name of the macro. A dw_macro is returned and must be used
in a subsequent call to DWMacFini (and possibly DWMacParam ).
DWMacParam
void DWENTRY DWMacParam( dw_client cli, dw_macro mac, const char *name );
Adds a parameter to the macro definition mac. name is the name of the parameter with no leading
or trailing white-space. The order of parameters must be the same as they appear in the source program.
DWMacFini
void DWENTRY DWMacFini( dw_client cli, dw_macro mac, const char *def );
Finishes the macro definition mac. def is the definition string.
DWMacUnDef
void DWENTRY DWMacUnDef( dw_client cli, dw_linenum line, const char *name );
Undefines the macro named name.
DWMacUse
void DWENTRY DWMacUse( dw_client cli, dw_linenum line, const char *name );
Indicate where the macro named name is used.
File and Line-Number Management
DWSetFile
void DWENTRY DWSetFile( dw_client cli, const char *file );
Specifies the current file. The default is for the source_filename parameter from the dw_init_info to be the
current file.
DWLineNum
void DWLineNum( dw_client cli, uint info, dw_linenum line, uint col, dw_addr_offset addr );
Sets the current source line number and machine address. The line numbers information of all instructions, not
just declarations, are stored by this routine. Note that all source line numbers are relative to the beginning of their
corresponding source file. So the line number of the first line of an included file is one.
- Parameter
-
info
- The information about the line, which is established by the combination of the following bits:
- Bit
- Description
DW_LN_DEFAULT
- There is no special information about the line.
DW_LN_STMT
- The line is the beginning of a statement.
DW_LN_BLK
- The line is the beginning of a block.
line
- Source line number, numbered beginning with one on the first line of the file.
col
- Source column number, which begins at 1.
addr
- Address of instruction relative to the beginning of the compilation unit. If it is at all possible the client should
call DWLineNum with increasing addrs. The line parameter does not have to be increasing. The size of
the emitted line number information is smaller if increasing addrs are used (There is also an implementation limitation that
the maximum decrease of addr between two calls is 32768).
DWDeclFile
void DWENTRY DWDeclFile( dw_client cli, const char *name );
Subsequent declarations are from the file named name.
DWDeclPos
void DWENTRY DWDeclPos( dw_client cli, dw_linenum line, dw_column column );
The next declaration occurs at the indicated line and column in the source file set by the last call to DWDeclFile.
Note that the position is only used for the immediate next declaration. If there are multiple declarations on
the same line, then multiple calls should be made.
DWReference
void DWENTRY DWReference( dw_client cli, dw_linenum line, dw_column column, dw_handle dependant );
Indicate that in the source code there is a reference to the dependant. This reference is attributed to the
current scope of debugging information. (i.e., if it is done inside a structure, then the structure is considered to
be the "referencer").
Location Expression Routines
Many functions require a dw_loc_handle. These are handles for expressions that the debugger will evaluate.
A dw_loc_handle can be either a single expression, or a list of expressions created by DWListFini.
The BROWSER is only interested in whether a location expression is present or not; so when creating BROWSER output
the client may create an empty location expression and use that wherever appropriate.
The expressions are evaluated on a stack machine, with operations described later. In some cases the stack will
be initially empty, in other cases (such as when calculating the address of a structure field) some base address will be
on the stack.
A location expression is limited to roughly 64K. Since each op-code is a single byte, this shouldn't pose much
of a limitation (famous last words). The destination of the branch instructions DW_LOC_BRA and DW_LOC_SKIP
must be within 32K of the current instruction (This is a limitation of the DWARF format, not a limitation of the DW library).
DWLocInit
dw_loc_id DWENTRY DWLocInit( dw_client cli );
First function called to create a location expression for a symbol. An unique dw_loc_id is returned
to the front end.
DWLocNewLabel
dw_loc_label DWENTRY DWLocNewLabel( dw_client cli, dw_loc_id loc );
Create a label for the location expression being built in loc. This label can be used for forward or
backward references by DW_LOC_SKIP and DW_LOC_BRA.
DWLocSetLabel
void DWENTRY DWLocSetLabel( dw_client cli, dw_loc_id loc, dw_loc_label label );
Give the label label the address of the next operation emitted into the location expression loc.
DWLocReg
void DWENTRY DWLocReg( dw_client cli, dw_loc_id loc, uint reg );
This 'operation' informs the debugger that the value it seeks is in the register named by reg.
FIXME: need to define the possible values of reg.
DWLocStatic
void DWENTRY DWLocStatic( dw_client cli, dw_loc_id loc, dw_sym_handle sym );
This operation pushes the address of sym on the stack.
DWLocSegment
void DWENTRY DWLocSegment( dw_client cli, dw_loc_id loc, dw_sym_handle sym );
This operation pushes the segment of the address of sym on the stack.
DWLocConstU
void DWENTRY DWLocConstU( dw_client cli, dw_loc_id loc, dw_uconst value );
Pushes an atom which is has an unsigned constant value value.
DWLocConstS
void DWENTRY DWLocConstS( dw_client cli, dw_loc_id loc, dw_sconst value );
Pushes an atom which is has a signed constant value value.
DWLocOp0
void DWENTRY DWLocOp0( dw_client cli, dw_loc_id loc, dw_loc_op op );
Performs one of the operations listed below.
- Operation
- Description
DW_LOC_ABS
- It pops the top stack entry and pushes its absolute value.
DW_LOC_AND
- It pops the top two stack values, performs the logical AND operation on the two, and pushes the result.
DW_LOC_DEREF
- It pops the top stack entry and treats it as an address. The value retrieved from that address is pushed. The
size of data retrieved from the dereferenced address is an addressing unit.
DW_LOC_DIV
- It pops the top two stack values, divides the former second entry by the former top of the stack using signed division, and
pushes the result.
DW_LOC_DROP
- It pops the value at the top of the stack.
DW_LOC_DUP
- It duplicates the value at the top of the stack.
DW_LOC_EQ
- Pop two entries from stack, push 1 if they are equal; push 0 otherwise.
DW_LOC_GE, DW_LOC_GT, DW_LOC_LE, DW_LOC_LT
- These operation pop the top two stack values, compare the former top of stack from the former second entry, and pushes 1 onto
stack if the comparison is true, 0 if it is false. The comparisons are signed comparison.
DW_LOC_MINUS
- It pops the top two stack values, subtracts the former top of the stack from the former second entry, and pushes the result.
DW_LOC_MOD
- It pops the top two stack values, and pushes the result of the calculation: former second stack entry modulo the former
top of the stack.
DW_LOC_MUL
- It pops the top two stack values, multiplies them together, and pushes the result.
DW_LOC_NE
- Pop two entries from stack, push 0 if they are equal; push 1 otherwise.
DW_LOC_NEG
- It pops the top value and pushes its negation.
DW_LOC_NOP
- A placeholder; has no side-effects.
DW_LOC_NOT
- It pops the top value and pushes its logical complement.
DW_LOC_OR
- It pops the top two stack entries, performs the logical OR operation on them, and pushes the result.
DW_LOC_OVER
- It duplicates the entry currently second in the stack at the top of the stack.
DW_LOC_PLUS
- It pops the top two stack entries, and pushes their sum.
DW_LOC_ROT
- It rotates the first three stack entries. The entry at the top of the stack becomes the third entry, the second entry
becomes the top, and the third entry becomes the second.
DW_LOC_SHL
- It pops the top two stack entries, shifts the former second entry left by the number of bits specified by the former top of
the stack, and pushes the result.
DW_LOC_SHR
- It pops the top two stack entries, shifts the former second entry right (logically) by the number of bits specified by the
former top of the stack, and pushes the result.
DW_LOC_SHRA
- It pops the top two stack entries, shifts the former second entry right (arithmetically) by the number of bits specified by
the former top of the stack, and pushes the result.
DW_LOC_SWAP
- It swaps the top two stack entries.
DW_LOC_XDEREF
- It provides an extended dereference mechanism. The entry at the top of the stack is treated as an address. The
second stack entry is treated as an "address space identifier" for those architectures that support multiple address
spaces. The top two stack elements are popped, a data item is retrieved through an implementation-defined address calculation
and pushed as the new stack top. The size of data retrieved is an addressing unit.
DW_LOC_XOR
- It pops the top two stack entries, performs the logical EXCLUSIVE-OR operation on them, and pushes the result.
DWLocOp
void DWENTRY DWLocOp( dw_client cli, dw_loc_id loc, dw_loc_op op, ... );
Performs one of the following operations:
- Operation
- Description
DW_LOC_BRA
- It is followed by a dw_loc_label operand. This operation pops the top stack entry, if the value is not zero, then jump
to the label.
DW_LOC_BREG
- Followed by two operands, the first is a register, and the second is an dw_sconst to add to the value in the register.
The result is pushed onto the stack.
DW_LOC_FBREG
- Takes one dw_sconst parameter which is added to the value calculated by the frame_base_loc parameter to the current subroutine,
then pushed on the stack.
DW_LOC_PICK
- It is followed by a uint operand which is an index. The stack entry with the specified index (0 through 255, inclusive;
0 means the top) is pushed on the stack.
DW_LOC_PLUS_UCONST
- It is followed an dw_uconst operand. It pops the top stack entry, adds it to the operand and pushes the result.
DW_LOC_SKIP
- It is followed by a dw_loc_label operand. Control is transferred immediately to this label.
DWLocFini
dw_loc_handle DWENTRY DWLocFini( dw_client cli, dw_loc_id loc );
Ends the location expression for a symbol, and returns a handle that may be passed to other DW routines.
DWListInit
dw_list_id DWENTRY DWListInit( dw_client cli );
First function called to create a location list for a symbol.
DWListEntry
void DWENTRY DWListEntry( dw_client cli, dw_list_id id, dw_sym_handle beg, dw_sym_handle end, dw_loc_handle loc );
Define an entry in the location list.
- Parameter
-
beg
- A beginning address. This address is relative to the base address of the compilation unit referencing this location
list. It marks the beginning of the range over which the location is valid.
end
- A ending address. This address is relative to the base address of the compilation unit referencing this location list.
It marks the first address past the end of the range over which the location is valid. Overlapping ranges are
possible and are interpreted to mean that the value may be found in one of many places during the overlap. A CLIReloc
for DW_W_LABEL will be made for each dw_sym_handle.
loc
- A location expression describing the location of the object over the range specified by the beginning and end addresses.
DWListFini
dw_loc_handle DWENTRY DWListFini( dw_client cli, dw_list_id );
Finishes the creation of the location list.
DWLocTrash
void DWENTRY DWLocTrash( dw_client cli, dw_loc_handle loc );
Frees the memory associated with the location expression or list loc. A location expression/list can be created
and used over and over again until it is freed by calling this function.
Unless otherwise noted, calls to these functions emit debugging information immediately. The DWARF format requires
that debugging information appear in the same order as it does in the source code. So, for example, a structure's fields
must be created in the same order that they appear in the source program.
Some of the following functions have common parameters. Here is the documentation for these common parameters:
- Parameter
-
char *name
- A null-terminated type name. i.e., "struct foobar {}" has the name foobar. If this parm is NULL then
no name is emitted.
dw_addr_offset start_scope
- This is the offset from the low_pc value for the enclosing block that the declaration occurs at. This is most commonly
0.
uint flags
- Some routines have additional flags available here; but unless otherwise noted, the following are always available:
- Flag
- Description
DW_DECLARATION
- The object is a declaration, not a definition
DW_FLAG_PRIVATE
- The object has the C++ private attribute.
DW_FLAG_PROTECTED
- The object has the C++ protected attribute.
DW_FLAG_PUBLIC
- The object has the C++ public attribute.
DWFundamental
dw_handle DWENTRY DWFundamental( dw_client cli, char * name, unsigned fund_idx, unsigned size );
Get a handle for a fundamental type. fund_idx is one of the following:
- DW_FT_ADDRESS
-
DW_FT_BOOLEAN
-
DW_FT_COMPLEX_FLOAT
-
DW_FT_FLOAT
-
DW_FT_SIGNED
-
DW_FT_SIGNED_CHAR
-
DW_FT_UNSIGNED
-
DW_FT_UNSIGNED_CHAR
-
For convenience, DW_FT_MIN, and DW_FT_MAX are defined. A valid fundamental type is in the range DW_FT_MIN <=
ft < DW_FT_MAX. The DW library will always return the same handle when called with the same fundamental type (so
the client does not need to save fundamental type handles).
- Parameter
-
name
- The name of the type being defined.
size
- The size in bytes of the type being defined.
DWModifier
dw_handle DWENTRY DWModifier( dw_client cli, dw_handle base_type, uint modifiers );
Specifies a modifier to a type. base_type is the base type to be modified with the modifier modifier.
The available modifiers are:
- Modifier Constant
- Description
DW_MOD_CONSTANT
- The object is a constant
DW_MOD_VOLATILE
- The object is volatile.
DW_MOD_NEAR
- The object is a near object.
DW_MOD_FAR
- The object is a far object.
DW_MOD_HUGE
- The object is a huge object.
DW_MOD_FAR16
- The object is a far16 object.
DWTypedef
dw_handle DWENTRY DWTypedef( dw_client cli, dw_handle base_type, const char *name, dw_addr_offset start_scope, uint
flags );
This function gives a name to a type. The name must not be NULL. The flag value DW_FLAG_DECLARATION
is not allowed.
DWPointer
dw_handle DWENTRY DWPointer( dw_client cli, dw_handle base_type, uint flags );
Declares a pointer type.
- Parameter
-
base_type
- The pointed-at type.
flags
- Only the following flags are available:
- Flags
- Description
DW_FLAG_REFERENCE
- Declare a pointer that is dereferenced automatically.
DW_PTR_TYPE_NORMAL
- A normal pointer (i.e. a model dependant pointer).
DW_PTR_TYPE_NEAR16
- A near 16-bit pointer.
DW_PTR_TYPE_FAR16
- A far 16-bit pointer.
DW_PTR_TYPE_HUGE
- A huge 16-bit pointer.
DW_PTR_TYPE_NEAR32
- A near 32-bit pointer.
DW_PTR_TYPE_FAR32
- A far 32-bit pointer.
DWString
dw_handle DWENTRY DWString( dw_client cli, dw_loc_handle string_length, dw_size_t byte_size, const char *name, dw_addr_offset
start_scope, uint flags );
Declares a type to be a block of characters.
- Parameter
-
string_length
- If this parameter is non-NULL then it is a location expression that the debugger executes to get the address where the length
of the string is stored in the program. In this case the byte_size parameter describes the number of bytes
to be retrieved at the location calculated. If byte_size is 0, then the debugger will use sizeof( long
).
byte_size
- If string_length is NULL then this parameter is the number of bytes in the string. Otherwise see string_length.
DWMemberPointer
dw_handle DWENTRY DWMemberPointer( dw_client cli, dw_handle containing_struct, dw_loc_handle use_location, dw_handle
base_type, const char *name, unsigned flags );
Declares a C++ pointer type to a data or function member of a class or structure.
- Parameter
-
containing_struct
- A handle to the class or struct to whose members objects of this type may point.
use_location
- This refers to the location expression which describes how to get to the member it points to from the beginning of the entire
class. It expects the base address of the structure/class object to be on the stack before the debugger starts to execute
the location description.
base_type
- The type of the member to which this object may point to.
Array Types
DWBeginArray
dw_handle DWENTRY DWBeginArray( dw_client cli, dw_handle elt_type, uint stride_size, const char *name, dw_addr_offset
scope, uint flags );
Begin the declaration of an array. This function call must be followed by calls to DWArrayDimension
and DWEndArray.
- Parameter
-
elt_type
- Handle for the type of the elements of this array.
stride_size
- If this value is non-zero then it indicates the number of bits of each element of the array (Useful if the number of bits
used to store an element in the array is different from the number of bits used to store an individual element of type
elt_type ).
DWArrayDimension
void DWENTRY DWArrayDimension( dw_client cli, const dw_dim_info *info );
Add a dimension to the previously started array. This function must be called for each dimension in the order
that the dimensions appear in the source program. info points to an instance of the following structure:
typedef struct {
dw_handle index_type;
dw_uconst lo_data;
dw_uconst hi_data;
} dw_dim_info;
- Field
- Description
hi_bound_fmt
- This is similar to lo_bound_fmt but describes the high bound of this dimension.
index_type
- This is the handle of the type of the indicies for this dimension.
lo_data
- The low bound of the array.
hi_data
- The upper bound of the array.
DWEndArray
void DWENTRY DWEndArray( dw_client cli, dw_handle array_hdl, dw_handle elt_type, uint stride_size, const char *name,
dw_addr_offset scope, uint flags );
This finishes the writing of the record to describe the array A sufficient number of calls to DWArrayDimension
must have been made before DWEndArray is called.
Structure Types
DWStruct
dw_handle DWENTRY DWStruct( dw_client cli, uint kind );
Create a handle for a structure type that will be defined later. This handle can be used for other DW routines
even before DWBeginStruct has been called.
- Kind
- Description
DW_ST_CLASS
- A C++ class type.
DW_ST_STRUCT
- A structure type.
DW_ST_UNION
- A union type.
DWBeginStruct
void DWENTRY DWBeginStruct( dw_client cli, dw_handle struct_hdl, dw_size_t size, const char *name, dw_addr_offset scope,
uint flags );
Begin the declaration of the structure reserved by a call to DWStruct. This function begins a nesting
of the debugging information. Subsequent calls, up to the corresponding DWEndStruct call, to the DW library
become children of this structure. i.e., this function marks the beginning of the scope of the structure definition.
- Parameter
-
struct_hdl
- A dw_handle returned by a call to DWStruct.
size
- If this is non-zero it indicates the number of bytes required to hold an element of this structure including any padding bytes.
DWAddFriend
void DWENTRY DWAddFriend( dw_client cli, dw_handle friend );
Add friend as a friend to the current structure.
DWAddInheritance
dw_handle DWENTRY DWAddInheritance( dw_client cli, dw_handle ancestor, dw_loc_handle loc, uint flags );
Indicate the the current structure inherits from another structure.
- Parameter
-
ancestor
- The handle of the ancestor to be inherited.
loc
- A location expression that describes the location of the beginning of the data members contributed to the entire class by
the ancestor relative to the beginning of the address of the data members of the entire class.
flags
- In addition to the common values of flags , the flag DW_FLAG_VIRTUAL may be supplied to indicate that the
inheritance serves as a virtual base class. As well, the flag DW_FLAG_DECLARATION is not allowed here.
DWAddField
dw_handle DWENTRY DWAddField( dw_client cli, dw_handle field_hdl, dw_loc_handle loc, const char *name, uint flags );
Add a data member to a structure.
- Parameter
-
field_hdl
- The dw_handle of the type of this field.
loc
- A location expression which expects the base address of the structure to be pushed on the stack and calculates the base address
of this field. If the structure is a union type, then this parameter may be NULL. If this is a static data member
of a class then this parameter may be NULL if the actual definition of the parameter is outside the class.
flags
- The additional flag DW_FLAG_STATIC may be used to indicate a static structure member.
DWAddBitField
dw_handle DWENTRY DWAddBitField( dw_client cli, dw_handle field_hdl, dw_loc_handle loc, dw_size_t byte_size, uint bit_offset,
uint bit_size, const char *name, uint flags );
Add a bitfield member to a structure.
- Parameter
-
field_hdl
- the dw_handle of the type of this field.
loc
- A location expression which expects the base address of the structure most closely containing the bit field to be pushed and
the stack, and which calculates the base address of this field.
byte_size
- This field must be the non-zero byte size of the unit of storage containing the bit-field. This is required only if
the storage required cannot be determined by the type of the bit-field (i.e., padding bytes). If the size can be determined
by the type of the bit-field, then this value may be 0.
bit_offset
- The number of bits to the left of the leftmost (most significant); bit of the bit field value.
bit_size
- The number of bits occupied by this bit-field value.
DWEndStruct
void DWENTRY DWEndStruct( dw_client cli );
End the current structure. Client must ensure proper Begin/End matching.
Enumeration Types
DWBeginEnumeration
dw_handle DWENTRY DWBeginEnumeration( dw_client cli, dw_size_t byte_size, const char *name, dw_addr_offset scope, uint
flags );
Begin the definition of an enumerated type. byte_size is the number of bytes required to hold an instance
of this enumeration. This call must be followed by calls to DWAddEnumerationConstant and DWEndEnumeration.
No other DW calls may be made before the call to DWEndEnumeration. The DWARF standard requires that
the constants be defined in reverse order to which they appear in the source program.
DWAddEnumerationConstant
void DWENTRY DWAddEnumerationConstant( dw_client cli, dw_uconst value, const char *name );
Add the constant value (that is byte_size bytes large as determined by the parameter to DWBeginEnumeration
); with the name name to the current enumeration.
DWEndEnumeration
void DWENTRY DWEndEnumeration( dw_client cli );
Finish the current enumeration.
Subroutine Type Declarations
These function calls deal with declarations of subroutines. That is, their prototypes, or for use in creating function
pointers.
DWBeginSubroutineType
dw_handle DWENTRY DWBeginSubroutineType( dw_client cli, dw_handle return_type, const char *name, dw_addr_offset scope,
uint flags );
Begin the nested declaration of the subroutine type. All calls to the DW library after this, until DWEndSubroutineType
are in the scope of the declaration of the subroutine type (i.e., if it's a prototyped C function, then declarations before
DWEndSubroutineType are similar to declarations inside the prototype). Parameters for this type are declared using
the entries DWAddParmToSubroutineType and DWAddEllipsisToSubroutineType.
- Parameter
-
return_type
- If the function is void, this parameter must be NULL. Otherwise it is a handle for the return type of the subroutine.
flags
- In addition to the standard flags, DW_FLAG_PROTOTYPED indicates that the declaration of the subroutine type was prototyped
in the source code. As well, the "address class" set of flags used in DWPointer are also allowed
here (e.g. DW_TYPE_FAR16 etc.)
DWEndSubroutineType
void DWENTRY DWEndSubroutineType( dw_client cli );
The client must ensure that proper Begin/End matching is done.
Lexical Blocks
DWBeginLexicalBlock
dw_handle DWENTRY DWBeginLexicalBlock( dw_client cli, dw_loc_handle segment, const char *name );
Begin a new lexical scope. name may be NULL indicating an un-named scope. Two CLIReloc calls
will made, one for DW_W_LOW_PC and one for DW_W_HIGH_PC which indicate the first byte of the scope, and
the first byte beyond the end of the scope. segment if non-null is an expression that evaluates to the segment
this block is in.
DWEndLexicalBlock
void DWENTRY DWEndLexicalBlock( dw_client cli );
End a lexical scope. As usual, the client must ensure that Begin/End pairs match.
Common Blocks
DWBeginCommonBlock
dw_handle DWENTRY DWBeginCommonBlock( dw_client cli, dw_loc_handle loc, dw_loc_handle segment, const char *name, unsigned
flag );
Begin the declarations for the common block named name and located at loc. segment
if non-null indicates which segment the common block is in. The only flag that is valid for the flag parameter
is DW_FLAG_DECLARATION.
DWEndCommonBlock
void DWENTRY DWEndCommonBlock( dw_client cli );
End of declarations for the common block.
DWIncludeCommonBlock
dw_handle DWENTRY DWIncludeCommonBlock( dw_client cli, dw_handle common_block );
Used in the subroutine scope that references the common block.
Subroutines
DWBeginInlineSubroutine
dw_handle DWENTRY DWBeginInlineSubroutine( dw_client cli, dw_handle out_of_line, dw_loc_handle ret_addr, dw_loc_handle
segment );
Begin a definition of a particular instance of an inlined subroutine. out_of_line is a handle to the
"out of line" instance of the subroutine (i.e., a handle from a DWBeginSubroutine call that had the DW_FLAG_OUT_OF_LINE
flag). Each instance of the inlined subroutine must have it's own copies of entries describing parameters to that subroutine
and it's local variables. ret_addr gives the location of the return address (if any). segment
if non-null indicates which segment the expansion occurs in.
DWBeginSubroutine
dw_handle DWENTRY DWBeginSubroutine( dw_client cli, dw_call_type call_type, dw_handle return_type, dw_loc_handle return_addr_loc,
dw_loc_handle frame_base_loc, dw_loc_handle structure_loc, dw_handle member_hdl, dw_loc_handle segment, const char *name,
dw_addr_offset start_scope, uint flags );
Begin a declaration/definition of a subroutine or entry point. This begins a nesting of the debugging information,
and must be followed by calls to DWFormalParameter et al to declare the parameters, types, and variables for this
subroutine. Unless DW_FLAG_DECLARATION is set, this will require a DW_W_LOW_PC and/or a DW_W_HIGH_PC.
- Parameter
-
call_type
- Not currently used, but should be one of:
- DW_SB_NEAR_CALL
-
DW_SB_FAR_CALL
-
DW_SB_FAR16_CALL
-
return_type
- Handle for the return type. Must be NULL for void-type subroutines.
return_addr_loc
- If non-NULL then this is a location expression that calculates the address of memory that stores the return address.
frame_base_loc
- If non-NULL then this is a location expression that describes the "frame base" for the subroutine or entry point
(If the frame base changes during the subroutine, it might be desirable for local variables to be calculated from the frame
base, and then use a location list for the frame base).
structure_loc
- For member functions of structure types, this calculates the address of the slot for the function within the virtual function
table for the enclosing class or structure.
member_hdl
- If this is a definition of a member function occuring outside the body of the structure type, then this is the handle for
the type definition of the structure.
segment
- If non-null then this is a location expression that evaluates to the segment for this subprogram.
The following additional flags are available:
- flag
- description
DW_FLAG_PROTOTYPED
- The function was declared with ANSI-C style prototyping, as opposed to K&R-C style parameter lists.
DW_FLAG_ARTIFICIAL
- The function was created by the compiler (i.e. not explicitly declared in any of the user's source files)
DW_FLAG_VIRTUAL
- This is a virtual subroutine.
DW_FLAG_PURE_VIRTUAL
- This is a pure virtual subroutine.
DW_FLAG_MAIN
- For Fortran PROGRAM-type subroutines.
DW_SUB_STATIC
- A file static subroutine or function. Also used for a static member function, and for nested subroutine declarations.
DW_SUB_ENTRY
- A FORTRAN Entry point. DW requires only a DW_W_LOW_PC for this type of function.
DW_FLAG_WAS_INLINED
- The function was generated inline by the compiler.
DW_FLAG_DECLARED_INLINED
- The function was declared inline by the user.
DWEndSubroutine
void DWENTRY DWEndSubroutine( dw_client cli );
End the current nesting of DWBeginSubroutine or DWBeginInlineSubroutine.
dw_handle DWENTRY DWFormalParameter( dw_client cli, dw_handle parm_type, dw_loc_handle parm_loc, dw_loc_handle segment,
const char *name, uint default_value_type, ... );
Declare a formal parameter to the current function.
- parm_type
- The type of the parameter.
parm_loc
- A location description that yields the address of the parameter. May be NULL indicating unknown address.
segment
- A location expression that yields the segment of the parameter. May be NULL indicating the default segment.
default_value_type
- One of the following:
- DW_DEFAULT_NONE
- There is no default value for this parameter.
DW_DEFAULT_FUNCTION
- The default value for this parameter is returned by a function with no args, that is specified by a CLIReloc for DW_W_DEFAULT_FUNCTION.
DW_DEFAULT_STRING
- The default value is a null-terminated string that is specified as an extra parameter to this DWFormalParameter.
DW_DEFAULT_BLOCK
- The default value is a constant block of data that is specified by extra "const void *" and "dw_size_t"
parameters to DWFormalParameter.
...
- Extra parameters depend on the default_value_type.
DWEllipsis
dw_handle DWENTRY DWEllipsis( dw_client cli );
Indicate that the current subroutine has unspecified parameters. Used for "..." in C.
DWLabel
dw_handle DWENTRY DWLabel( dw_client cli, dw_loc_handle segment, const char *name, dw_addr_offset start_scope );
Declare a label inside a subroutine. start_scope will usually be 0, but is here for future compatibility.
A CLIReloc for DW_W_LABEL will be made. segment if non-null indicates which segment the label
belongs to.
DWVariable
dw_handle DWENTRY DWVariable( dw_client cli, dw_handle type, dw_loc_handle loc, dw_handle member_of, dw_loc_handle
segment, const char *name, dw_addr_offset start_scope, uint flags );
Declare a variable.
- type
- The type of this variable.
loc
- A location expression yielding the address of this variable.
member_of
- If this is the definition of a static data member then this is the handle to the structure type. Otherwise this is NULL.
segment
- If this is non-null then it evaluates to the segment the variable is in.
flags
- If DW_FLAG_GLOBAL is set then this is a global variable. Otherwise it is a local variable. File static
variables in C and C++ are considered local variables. If DW_FLAG_ARTIFICIAL is set then this is a variable
that has been created by the compiler.
DWConstant
dw_handle DWENTRY DWConstant( dw_client cli, dw_handle type, const void *value, dw_size_t len, dw_handle member_of,
const char *name, dw_addr_offset start_scope, uint flags );
Declare a named constant.
- type
- The type of this constant.
value
- Pointer to the value for this constant.
len
- The length of this constant. If len is 0, then value is considered to be a null-terminated string.
member_of
- If this is the definition of a constant member of a structure type, then this is the handle to the structure type. Otherwise
it is NULL.
DWAddress
void DWENTRY DWAddress( dw_client cli, uint_32 len );
DWARF builds a table of all the addresses attributed to a compilation unit. The client calls this function to
add addresses to this table. len is the length of this address range. The base of the address range
is filled in by a CLIReloc for DW_W_ARANGE_ADDR.
DWPubname
void DWENTRY DWPubname( dw_client cli, dw_handle hdl, const char *name );
These are used to speed up the debugger. This should be called for any name that has global scope.
hdl is the handle for the debugging entry that declares/defines the name.
Required Client Routines
The debugging information has several sections indicated by the following enumerated type:
- Constant
- Description
DW_DEBUG_INFO
- This section is called .debug_info , which stores all the debugging information entries.
DW_DEBUG_PUBNAMES
- This section is called .debug_pubnames , which stores a table consisting of object name information that is
used in lookup by Name.
DW_DEBUG_ARANGES
- This section is called .debug_aranges , which stores a table consisting of object address information that is
used in lookup by Address.
DW_DEBUG_LINE
- This section is called .debug_line , which stores the line number information generated for the compilation
units.
DW_DEBUG_LOC
- This section is called .debug_loc , which stores the location lists information.
DW_DEBUG_ABBREV
- This section is called .debug_abbrev , which stores abbreviation declarations.
DW_DEBUG_MACINFO
- This section is called .debug_macinfo , which stores macro information.
DW_DEBUG_REF
- This section is called .WATCOM_references , which contains information about the symbols of every instructions
in the source files.
DW_DEBUG_MAX
- Defined for convenience; it is the number of sections.
The DW library does it's best to try and group CLIWrite operations together into one larger CLIWrite, and to try and avoid
using CLISeek. But the library does not go out of it's way to provide this massaging of output. The client should
attempt to buffer the data itself. CLISeek is most often called on the DW_DEBUG_INFO, and the DW_DEBUG_LOC sections.
The other sections may have one CLISeek performed at the DWFini stage, and the seek will be to the zero offset.
The client might wish to optimize performance for only the DW_DEBUG_INFO and the DW_DEBUG_LOC sections.
CLISeek
void CLISeek( uint section, long offset, uint mode );
Repositions the pointer in section so that subsequent output occurs at the new pointer.
- Mode
- Description
DW_SEEK_SET
- The position is set to the absolute location offset.
DW_SEEK_CUR
- offset is added to the current position.
DW_SEEK_END
- The position is set to offset bytes from the current end of section.
CLITell
long CLITell( uint section );
Return the offset of the next byte to be written to the section.
CLIReloc
void CLIReloc( uint section, uint reloc_type, ... );
Even when writing BROWSER information, relocations such as DW_W_LOC_PC may be asked for. This is because the
DWARF format requires the presence of certain fields to indicate something specific about a record. For example, if
a subroutine record doesn't have a low pc then it is assumed to be a declaration of the subroutine rather than a definition.
- Parameter
-
section
- The section to write a relocation entry to.
reloc_type
- The type of the relocation, as follows:
- DW_W_LOW_PC
- Emit a dw_targ_addr. Used by various entry points to get the low pc address of an object.
DW_W_HIGH_PC
- Emit a dw_targ_addr. Used by various entry points to get the high pc address of an object.
DW_W_STATIC
- Emit a dw_targ_addr. This relocation has an extra parameter of type dw_sym_handle. This parameter is the target
of the relocation; the offset of the symbol should be generated. This is used any time a location expression involving
a DWLocStatic is generated.
DW_W_SEGMENT
- Emit a dw_segment. This relocation has an extra parameter of type dw_sym_handle. It indicates that the segment
portion of the address of the symbol should be generated. This is used any time a location expression involving a
DWLocSegment operation is generated.
DW_W_LABEL
- Emit a dw_targ_addr. Used by DWLabel.
DW_W_SECTION_POS
- Emit a uint_32. This relocation has an extra parameter of type uint called targ_sect. targ_sect
parameter is the number of a section for which the current offset is the target of the relocation. The relocation is
emitted into section.
DW_W_DEFAULT_FUNCTION
- Emit a dw_targ_addr. Used by DWFormalParameter.
DW_W_ARANGE_ADDR
- Emit a dw_targ_addr. Used by DWAddress.
DW_W_UNIT_SIZE
- Emit an uint_32 that is the number of bytes of code in the current compilation unit.
DW_W_MAX
- Defined for convenience. This enumerated type starts at 0 and goes to DW_W_MAX.
CLIWrite
void CLIWrite( uint section, const void *block, size_t len );
Writes out the debugging information.
- Parameter
-
section
- The section to which the debugging information is written.
block
- Points to the debugging information block.
len
- Length of the debugging information block.
CLIAlloc
void *CLIAlloc( size_t size );
Allocates a memory block of size size for the library and returns its address. This function cannot
return NULL.
CLIFree
void CLIFree( void *blk );
Free the block pointed by blk.
Examples
This section needs a major rewrite.
The example below shows what functions should be called in order to store the debugging information for this C program.
N.B. In this example, for all the CLIWrite() calls, only the section id is accurate. Also for all DWLineNum()
calls, the advances in machine instruction address are inaccurate.
test.c:
1 #include <stdlib.h>
2 int a;
3 typedef near char NCHAR;
4 void main()
5 {
6 NCHAR b;
7 b := 5;
8 }
Functions called by the client and the DWARF library.
Client:
cli_id = DWInit( DW_LANG_C89, DW_CM_DEBUGGER, "test.c",
"c:\mydir", 0x123, 1, CLILoc, CLIType,
CLIName, CLIWrite, CLIAlloc, CLIFree );
DWARF Library:
/* Initialize the .debug_line section */
CLIWrite( DW_DEBUG_LINE, 0, &info, 20, block );
/* Initialize the .debug_abbrevs section */
CLIWrite( DW_DEBUG_ABBREVS, 0, &info, 50, block );
/* Initialize the .debug_pubnames section */
CLIWrite( DW_DEBUG_PUBNAMES, 0, &info, 50, block );
/* Initialize the .debug_aranges section */
CLIWrite( DW_DEBUG_ARANGES, 0, &info, 50, block );
/* Write all strings to the string table */
CLIWrite( DW_DEBUG_STR, 0, &info, 17, block );
Client:
#include <stdlib.h>
DWLineNum( cli_id, DW_LN_STMT|DW_LN_BLK, 1, 1, 0 );
DWIncl( id, "stdlib.h" );
...Function calls for "stdlib.h"...
DWInclFini( cli_id );
DWARF Library:
CLIWrite( DW_DEBUG_LINE, 0, &info, 28, block );
CLIWrite( DW_DEBUG_INFO, 30, &info, 12, block );
Client:
int a;
DWLineNum( cli_id, DW_LN_STMT, 1, 1, 4 );
a_dw_handle = DWModSym( cli_id, a_cg_handle, DW_SM_VAR,
DW_SM_GLO|DW_SM_FILE, DW_SM_NULL );
DWARF Library:
name = CLIName( a_cg_handle );
/* It returns the string "a". */
type = CLIType( a_cg_handle );
/* It returns DW_FT_INTEGER. */
loc = CLILoc( a_cg_handle );
CLIWrite( DW_DEBUG_LINE, 0, &info, 28, block );
CLIWrite( DW_DEBUG_INFO, 0, &info, 24, block );
CLIWrite( DW_DEBUG_PUBNAMES, 0, &info, 12, block );
Inside CLILoc():
loc_id = DWLocInt();
DWLocAtom( cli_id, a_cg_handle, DW_LOC_STATIC );
/* The actual address will be filled in by the client when
the debugging information is written to the
object file.*/
a_loc_hd = DWLocFini( loc_id );
return a_loc_hd;
Client:
typedef near char NCHAR;
DWLineNum( cli_id, DW_LN_STMT, 1, 1, 14 );
mod_handle = DWMod( cli_id, DW_FT_CHAR, DW_MOD_NEAR );
nchar_handle = DWModSym( cli_id, nchar_cg_handle,
DW_SM_TYPEDEF, DW_SM_NULL,
DW_SM_NULL );
DWARF Library:
name = CLIName( nchar_cg_handle );
/* It returns the string "NCHAR". */
type = CLIType( nchar_cg_handle );
/* It returns mod_handle. */
CLIWrite( DW_DEBUG_LINE, 0, &info, 20, block );
CLIWrite( DW_DEBUG_INFO, 0, &info, 24, block );
Client:
void main()
DWLineNum( cli_id, DW_LN_DEFAULT, 1, 1, 23 );
pro_handle = DWBegProc( cli_id, DW_SB_NEAR_CALL, DW_FT_VOID,
ret_loc_hd, DW_LOC_NULL,
DW_SB_GLOBAL_SUB|DW_SB_FUNC_PROTOTYPE );
In order to get ret_loc_ad:
loc_id = DWLocInit();
DWLocAtom( cli_id, some_cg_handle, DW_LOC_STATIC );
/* Assume that the return address of main() is stored
in a symbol with some_cg_handle as its handle.
The actual address will be filled in by the
client when the debugging information is
written
to the object file.
*/
ret_loc_ad = DWLocFini( cli_id );
DWARF Library:
CLIWrite( DW_DEBUG_LINE, 0, &info, 20, block );
Client:
{
DWLineNum( cli_id, DW_LN_BLK, 1, 1, 0 );
DWARF Library:
CLIWrite( DW_DEBUG_LINE, 0, &info, 24, block );
Client:
NCHAR b;
DWLineNum( cli_id, DW_LN_STMT, 1, 1, 10 );
b_handle = DWModSym( cli_id, b_cg_handle, DW_SM_VAR,
DW_SM_NULL, DW_SM_LOC|DW_SM_ROUT );
DWARF Library:
loc = CLILoc( b_cg_handle );
name = CLIName( b_cg_handle );
/* It returns the string "b". */
type = CLIType( b_cg_handle );
/* It returns nchar_handle. */
CLIWrite( DW_DEBUG_LINE, 0, &info, 20, block );
Inside CLILoc():
loc_id = DWLocInt();
DWLocAtom( cli_id, b_cg_handle, DW_LOC_STACK );
/* The offset from stack frame base will be filled in by
the client when the debugging information
is written
to the object file. */
b_loc_hd = DWLocFini( loc_id );
return b_loc_hd;
Client:
b := 5;
DWLineNum( cli_id, DW_LN_STMT, 1, 4, 14 );
DWARF Library:
CLIWrite( DW_DEBUG_LINE, 0, &info, 24, block );
Client:
}
DWLineNum( cli_id, DW_LN_DEFAULT, 1, 1, 4 );
DWEndProc( cli_id, pro_handle );
main_handle = DWModSym( cli_id, main_cg_handle, DW_SM_SUB,
DW_SM_NULL, DW_SM_NULL );
DWARF Library:
name = CLIName( main_cg_handle );
/* It returns the string "main" */
type = CLIType( main_cg_handle );
/* It returns pro_handle */
CLIWrite( DW_DEBUG_LINE, 0, &info, 24, block );
CLIWrite( DW_DEBUG_INFO, -50, &info, 86, block );
CLIWrite( DW_DEBUG_REF, 0, &info, 12, block );
CLIWrite( DW_DEBUG_PUBNAMES, 0, &info, 12, block );
/* For the global object "main" */
Client:
DWFini( cli_id );
DWARF Library:
CLIWrite( DW_DEBUG_LINE, 0, &info, 24, block );
CLIWrite( DW_DEBUG_INFO, -120, &info, 54, block );
Revision History
- Draft 5
- Changed the arguments to a number of the function calls for use with draft 5 of dwarf.
Draft 6
- Changed the arguments to a number of the function calls for use with draft 6 of dwarf.