xref: /openbsd-src/gnu/usr.bin/binutils/gdb/rdi-share/armdbg.h (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1b725ae77Skettenis /*
2b725ae77Skettenis  * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3b725ae77Skettenis  *
4b725ae77Skettenis  * This software may be freely used, copied, modified, and distributed
5b725ae77Skettenis  * provided that the above copyright notice is preserved in all copies of the
6b725ae77Skettenis  * software.
7b725ae77Skettenis  */
8b725ae77Skettenis 
9b725ae77Skettenis /*
10b725ae77Skettenis  * ARM symbolic debugger toolbox interface
11b725ae77Skettenis  */
12b725ae77Skettenis 
13b725ae77Skettenis /*
14*63addd46Skettenis  * RCS $Revision: 1.3 $
15*63addd46Skettenis  * Checkin $Date: 2004/12/27 14:00:54 $
16b725ae77Skettenis  */
17b725ae77Skettenis 
18b725ae77Skettenis /* Minor points of uncertainty are indicated by a question mark in the
19b725ae77Skettenis    LH margin.
20b725ae77Skettenis 
21b725ae77Skettenis    Wherever an interface is required to iterate over things of some class,
22b725ae77Skettenis    I prefer something of the form  EnumerateXXs(..., XXProc *p, void *arg)
23b725ae77Skettenis    which results in a call of p(xx, arg) for each xx, rather than something
24b725ae77Skettenis    of the form
25b725ae77Skettenis      for (xxh = StartIterationOverXXs(); (xx = Next(xxh)) != 0; ) { ... }
26b725ae77Skettenis      EndIterationOverXXs(xxh);
27b725ae77Skettenis    Others may disagree.
28b725ae77Skettenis    (Each XXProc returns an Error value: if this is not Err_OK, iteration
29b725ae77Skettenis    stops immediately and the EnumerateXXs function returns that value).
30b725ae77Skettenis 
31b725ae77Skettenis    ptrace has been retired as of insufficient utility.  If such fuctionality is
32b725ae77Skettenis    required, it can be constructed using breakpoints.
33b725ae77Skettenis 
34b725ae77Skettenis    The file form of all name fields in debug areas is in-line, with a length
35b725ae77Skettenis    byte and no terminator.  The debugger toolbox makes an in-store translation,
36b725ae77Skettenis    where the strings are out of line (the namep variant in asdfmt.h) and have a
37b725ae77Skettenis    terminating zero byte: the pointer is to the first character of the string
38b725ae77Skettenis    with the length byte at ...->n.namep[-1].
39b725ae77Skettenis  */
40b725ae77Skettenis 
41b725ae77Skettenis #ifndef armdbg__h
42b725ae77Skettenis #define armdbg__h
43b725ae77Skettenis 
44b725ae77Skettenis #include <stddef.h>
45b725ae77Skettenis 
46b725ae77Skettenis #include "host.h"
47b725ae77Skettenis #include "msg.h"
48b725ae77Skettenis 
49b725ae77Skettenis typedef unsigned32 ARMaddress;
50b725ae77Skettenis typedef unsigned32 ARMword;
51b725ae77Skettenis typedef unsigned16 ARMhword;
52b725ae77Skettenis 
53b725ae77Skettenis #include "dbg_conf.h"
54b725ae77Skettenis #include "dbg_rdi.h"
55b725ae77Skettenis 
56b725ae77Skettenis #ifdef __cplusplus
57b725ae77Skettenis extern "C"
58b725ae77Skettenis {
59b725ae77Skettenis #endif
60b725ae77Skettenis 
61b725ae77Skettenis typedef unsigned char Dbg_Byte;
62b725ae77Skettenis 
63b725ae77Skettenis typedef int Dbg_Error;
64b725ae77Skettenis 
65b725ae77Skettenis typedef struct Dbg_MCState Dbg_MCState;
66b725ae77Skettenis /* A representation of the state of the target.  The structure is not revealed.
67b725ae77Skettenis    A pointer to one of these is returned by Dbg_Initialise(), is passed to all
68b725ae77Skettenis    toolbox calls which refer to the state of the target, and is discarded
69b725ae77Skettenis    by Dbg_Finalise().
70b725ae77Skettenis    Nothing in the toolbox itself precludes there being multiple targets, each
71b725ae77Skettenis    with its own state.
72b725ae77Skettenis  */
73b725ae77Skettenis 
74b725ae77Skettenis /* Most toolbox interfaces return an error status.  Only a few of the status
75b725ae77Skettenis    values are expected to be interesting to clients and defined here; the
76b725ae77Skettenis    rest are private (but a textual form can be produced by ErrorToChars()).
77b725ae77Skettenis  */
78b725ae77Skettenis 
79b725ae77Skettenis #define Error_OK 0
80b725ae77Skettenis 
81b725ae77Skettenis /* Partitioning of the error code space: errors below Dbg_Error_Base are RDI
82b725ae77Skettenis    errors (as defined in dbg_rdi.h). Codes above Dbg_Error_Limit are
83b725ae77Skettenis    available to clients, who may impose some further structure.
84b725ae77Skettenis  */
85b725ae77Skettenis #define Dbg_Error_Base 0x1000
86b725ae77Skettenis #define Dbg_Error_Limit 0x2000
87b725ae77Skettenis 
88b725ae77Skettenis #define DbgError(n) ((Dbg_Error)(Dbg_Error_Base+(n)))
89b725ae77Skettenis 
90b725ae77Skettenis #define Dbg_Err_OK Error_OK
91b725ae77Skettenis #define Dbg_Err_Interrupted             DbgError(1)
92b725ae77Skettenis #define Dbg_Err_Overflow                DbgError(2)
93b725ae77Skettenis #define Dbg_Err_FileNotFound            DbgError(3)
94b725ae77Skettenis #define Dbg_Err_ActivationNotPresent    DbgError(4)
95b725ae77Skettenis #define Dbg_Err_OutOfHeap               DbgError(5)
96b725ae77Skettenis #define Dbg_Err_TypeNotSimple           DbgError(6)
97b725ae77Skettenis #define Dbg_Err_BufferFull              DbgError(7)
98b725ae77Skettenis #define Dbg_Err_AtStackBase             DbgError(8)
99b725ae77Skettenis #define Dbg_Err_AtStackTop              DbgError(9)
100b725ae77Skettenis #define Dbg_Err_DbgTableFormat          DbgError(10)
101b725ae77Skettenis #define Dbg_Err_NotVariable             DbgError(11)
102b725ae77Skettenis #define Dbg_Err_NoSuchBreakPoint        DbgError(12)
103b725ae77Skettenis #define Dbg_Err_NoSuchWatchPoint        DbgError(13)
104b725ae77Skettenis #define Dbg_Err_FileLineNotFound        DbgError(14)
105b725ae77Skettenis #define Dbg_Err_DbgTableVersion         DbgError(15)
106b725ae77Skettenis #define Dbg_Err_NoSuchPath              DbgError(16)
107b725ae77Skettenis #define Dbg_Err_StateChanged            DbgError(17)
108b725ae77Skettenis #define Dbg_Err_SoftInitialiseError     DbgError(18)
109b725ae77Skettenis #define Dbg_Err_CoProRegNotWritable     DbgError(19)
110b725ae77Skettenis #define Dbg_Err_NotInHistory            DbgError(20)
111b725ae77Skettenis #define Dbg_Err_ContextSyntax           DbgError(21)
112b725ae77Skettenis #define Dbg_Err_ContextNoLine           DbgError(22)
113b725ae77Skettenis #define Dbg_Err_ContextTwoLines         DbgError(23)
114b725ae77Skettenis #define Dbg_Err_VarReadOnly             DbgError(24)
115b725ae77Skettenis #define Dbg_Err_FileNewerThanImage      DbgError(25)
116b725ae77Skettenis #define Dbg_Err_NotFound                DbgError(26)
117b725ae77Skettenis 
118b725ae77Skettenis    /* functions which evaluate expressions may return this value, to indicate
119b725ae77Skettenis       that execution became suspended within a function called in the debugee */
120b725ae77Skettenis 
121b725ae77Skettenis /* Functions returning characters take a BufDesc argument, with fields buffer
122b725ae77Skettenis    and bufsize being input arguments describing the buffer to be filled, and
123b725ae77Skettenis    filled being set on return to the number of bytes written to the buffer
124b725ae77Skettenis    (omitting the terminating 0).
125b725ae77Skettenis  */
126b725ae77Skettenis 
127b725ae77Skettenis typedef struct Dbg_BufDesc Dbg_BufDesc;
128b725ae77Skettenis 
129b725ae77Skettenis typedef void Dbg_BufferFullProc(Dbg_BufDesc *bd);
130b725ae77Skettenis 
131b725ae77Skettenis struct Dbg_BufDesc {
132b725ae77Skettenis     char *buffer;
133b725ae77Skettenis     size_t size,
134b725ae77Skettenis            filled;
135b725ae77Skettenis     Dbg_BufferFullProc *p;
136b725ae77Skettenis     void *arg;
137b725ae77Skettenis };
138b725ae77Skettenis 
139b725ae77Skettenis #define Dbg_InitBufDesc(bd, buf, bytes) \
140b725ae77Skettenis     ((bd).buffer = (buf), (bd).size = (bytes), (bd).filled = 0,\
141b725ae77Skettenis      (bd).p = NULL, (bd).arg = NULL)
142b725ae77Skettenis 
143b725ae77Skettenis #define Dbg_InitBufDesc_P(bd, buf, bytes, fn, a) \
144b725ae77Skettenis     ((bd).buffer = (buf), (bd).size = (bytes), (bd).filled = 0,\
145b725ae77Skettenis      (bd).p = (fn), (bd).arg = (a))
146b725ae77Skettenis 
147b725ae77Skettenis Dbg_Error Dbg_StringToBuf(Dbg_BufDesc *buf, char const *s);
148b725ae77Skettenis Dbg_Error Dbg_BufPrintf(Dbg_BufDesc *buf, char const *form, ...);
149b725ae77Skettenis #ifdef NLS
150b725ae77Skettenis Dbg_Error Dbg_MsgToBuf(Dbg_BufDesc *buf, msg_t t);
151b725ae77Skettenis Dbg_Error Dbg_BufMsgPrintf(Dbg_BufDesc *buf, msg_t form, ...);
152b725ae77Skettenis #else
153b725ae77Skettenis #define Dbg_MsgToBuf Dbg_StringToBuf
154b725ae77Skettenis #define Dbg_BufMsgPrintf Dbg_BufPrintf
155b725ae77Skettenis #endif
156b725ae77Skettenis Dbg_Error Dbg_CharToBuf(Dbg_BufDesc *buf, int ch);
157b725ae77Skettenis 
158b725ae77Skettenis int Dbg_CIStrCmp(char const *s1, char const *s2);
159b725ae77Skettenis /* Case-independent string comparison, interface as for strcmp */
160b725ae77Skettenis 
161b725ae77Skettenis int Dbg_CIStrnCmp(char const *s1, char const *s2, size_t n);
162b725ae77Skettenis /* Case-independent string comparison, interface as for strncmp */
163b725ae77Skettenis 
164b725ae77Skettenis void Dbg_ErrorToChars(Dbg_MCState *state, Dbg_Error err, Dbg_BufDesc *buf);
165b725ae77Skettenis 
166b725ae77Skettenis typedef int Dbg_RDIResetCheckProc(int);
167b725ae77Skettenis /* Type of a function to be called after each RDI operation performed by the
168b725ae77Skettenis    toolbox, with the status from the operation as argument.  The value returned
169b725ae77Skettenis    is treated as the status.  (The intent is to allow the toolbox's client to
170b725ae77Skettenis    take special action to handle RDIDbg_Error_Reset).
171b725ae77Skettenis  */
172b725ae77Skettenis 
173b725ae77Skettenis typedef struct Dbg_CoProDesc Dbg_CoProDesc;
174b725ae77Skettenis 
175b725ae77Skettenis typedef Dbg_Error Dbg_CoProFoundProc(Dbg_MCState *state, int cpno, Dbg_CoProDesc const *cpd);
176b725ae77Skettenis /* Type of a function to be called when the shape of a coprocessor is discovered
177b725ae77Skettenis    by enquiry of the target or agent (via RequestCoProDesc)
178b725ae77Skettenis  */
179b725ae77Skettenis 
180b725ae77Skettenis typedef struct RDIProcVec RDIProcVec;
181b725ae77Skettenis 
182b725ae77Skettenis Dbg_Error Dbg_RequestReset(Dbg_MCState *);
183b725ae77Skettenis 
184b725ae77Skettenis Dbg_Error Dbg_Initialise(
185b725ae77Skettenis     Dbg_ConfigBlock *config, Dbg_HostosInterface const *i,
186b725ae77Skettenis     Dbg_RDIResetCheckProc *checkreset, Dbg_CoProFoundProc *coprofound,
187b725ae77Skettenis     RDIProcVec const *rdi, Dbg_MCState **statep);
188b725ae77Skettenis /* values in config are updated if they call for default values */
189b725ae77Skettenis 
190b725ae77Skettenis void Dbg_Finalise(Dbg_MCState *state, bool targetdead);
191b725ae77Skettenis 
192b725ae77Skettenis typedef struct {
193b725ae77Skettenis     char name[16];
194b725ae77Skettenis     RDI_MemDescr md;
195b725ae77Skettenis     RDI_MemAccessStats a;
196b725ae77Skettenis } Dbg_MemStats;
197b725ae77Skettenis 
198b725ae77Skettenis /*--------------------------------------------------------------------------*/
199b725ae77Skettenis 
200b725ae77Skettenis /* Symbol table management.
201b725ae77Skettenis    The structure of a Dbg_SymTable is not revealed.  It is created by
202b725ae77Skettenis    Dbg_ReadSymbols() or by Dbg_LoadFile(), and associated with the argument
203b725ae77Skettenis    Dbg_MCState.
204b725ae77Skettenis    Many symbol tables may be concurrently active.
205b725ae77Skettenis    A Dbg_SymTable is removed either explicitly (by call to Dbg_DeleteSymbols)
206b725ae77Skettenis    or implicitly when a symbol table for an overlapping address range is read.
207b725ae77Skettenis 
208b725ae77Skettenis    There is a pre-defined symbol table containing entries for ARM registers,
209b725ae77Skettenis    co-processor registers and the like.
210b725ae77Skettenis  */
211b725ae77Skettenis 
212b725ae77Skettenis typedef struct Dbg_SymTable Dbg_SymTable;
213b725ae77Skettenis 
214b725ae77Skettenis typedef struct Dbg_ImageFragmentDesc {
215b725ae77Skettenis     ARMaddress base, limit;
216b725ae77Skettenis } Dbg_ImageFragmentDesc;
217b725ae77Skettenis 
218b725ae77Skettenis typedef enum {
219b725ae77Skettenis     Dbg_Lang_None,
220b725ae77Skettenis     Dbg_Lang_C,
221b725ae77Skettenis     Dbg_Lang_Pascal,
222b725ae77Skettenis     Dbg_Lang_Fortran,
223b725ae77Skettenis     Dbg_Lang_Asm,
224b725ae77Skettenis     Dbg_Lang_Cpp
225b725ae77Skettenis } Dbg_Lang;
226b725ae77Skettenis 
227b725ae77Skettenis typedef struct Dbg_ImageDesc {
228b725ae77Skettenis     Dbg_Lang lang;
229b725ae77Skettenis     int executable;
230b725ae77Skettenis     ARMaddress robase, rolimit, rwbase, rwlimit;
231b725ae77Skettenis     int nfrags;
232b725ae77Skettenis     Dbg_ImageFragmentDesc *fragments;
233b725ae77Skettenis     char *name;
234b725ae77Skettenis } Dbg_ImageDesc;
235b725ae77Skettenis 
236b725ae77Skettenis Dbg_ImageDesc *Dbg_ImageAreas(Dbg_SymTable *st);
237b725ae77Skettenis 
238b725ae77Skettenis Dbg_SymTable *Dbg_LastImage(Dbg_MCState *state);
239b725ae77Skettenis 
240b725ae77Skettenis Dbg_SymTable *Dbg_NewSymTable(Dbg_MCState *state, const char *name);
241b725ae77Skettenis 
242b725ae77Skettenis Dbg_Error Dbg_ReadSymbols(Dbg_MCState *state, const char *filename, Dbg_SymTable **st);
243b725ae77Skettenis /* Just read the symbols from the named image.  <st> is set to the allocated
244b725ae77Skettenis    symbol table.
245b725ae77Skettenis ?  Maybe we could usefully allow other formats than AIF images to describe
246b725ae77Skettenis    the symbols (eg) of shared libraries
247b725ae77Skettenis  */
248b725ae77Skettenis 
249b725ae77Skettenis typedef struct Dbg_SymInfo {
250b725ae77Skettenis     int isize;
251b725ae77Skettenis     ARMaddress addr;
252b725ae77Skettenis     char *name;
253b725ae77Skettenis } Dbg_SymInfo;
254b725ae77Skettenis 
255b725ae77Skettenis Dbg_SymInfo *Dbg_AsmSym(Dbg_SymTable *st, ARMaddress addr);
256b725ae77Skettenis int32 Dbg_AsmAddr(Dbg_SymTable *st, int32 line);
257b725ae77Skettenis int32 Dbg_AsmLine(Dbg_SymTable *st, ARMaddress addr);
258b725ae77Skettenis int32 Dbg_AsmLinesInRange(Dbg_SymTable *st, ARMaddress start, ARMaddress end);
259b725ae77Skettenis 
260b725ae77Skettenis Dbg_Error Dbg_LoadFile(Dbg_MCState *state, const char *filename, Dbg_SymTable **st);
261b725ae77Skettenis /* load the image into target memory, and read its symbols.  <st> is set to
262b725ae77Skettenis    the allocated symbol table.
263b725ae77Skettenis    A null filename reloads the most recently loaded file (and rereads its
264b725ae77Skettenis    symbols).
265b725ae77Skettenis    Loading an image leaves breakpoints unchanged.  If a client wishes
266b725ae77Skettenis    otherwise, it must remove the breakpoints explicitly.
267b725ae77Skettenis */
268b725ae77Skettenis 
269b725ae77Skettenis Dbg_Error Dbg_CallGLoadFile(Dbg_MCState *state, const char *filename, Dbg_SymTable **st);
270b725ae77Skettenis 
271b725ae77Skettenis typedef void Dbg_ImageLoadProc(Dbg_MCState *, Dbg_SymTable *);
272b725ae77Skettenis Dbg_Error Dbg_OnImageLoad(Dbg_MCState *, Dbg_ImageLoadProc *);
273b725ae77Skettenis /* Register function to be called back whenever an image is loaded, or symbols
274b725ae77Skettenis  * for an image read. (To allow multiple toolbox clients to coexist).
275b725ae77Skettenis  */
276b725ae77Skettenis 
277b725ae77Skettenis Dbg_Error Dbg_LoadAgent(Dbg_MCState *state, const char *filename);
278b725ae77Skettenis /* Load a debug agent, and start it.
279b725ae77Skettenis    Symbols in the image for the agent are ignored.
280b725ae77Skettenis */
281b725ae77Skettenis 
282b725ae77Skettenis Dbg_Error Dbg_RelocateSymbols(Dbg_SymTable *st, ARMaddress reloc);
283b725ae77Skettenis /* add <reloc> to the value of all symbols in <st> describing absolute memory
284b725ae77Skettenis    locations.  The intent is to allow the symbols in a load-time relocating
285b725ae77Skettenis    image (for example) to be useful.
286b725ae77Skettenis  */
287b725ae77Skettenis 
288b725ae77Skettenis Dbg_Error Dbg_DeleteSymbols(Dbg_MCState *state, Dbg_SymTable **st);
289b725ae77Skettenis 
290b725ae77Skettenis typedef enum Dbg_LLSymType {
291b725ae77Skettenis     llst_code,
292b725ae77Skettenis     llst_code16,
293b725ae77Skettenis     llst_data,
294b725ae77Skettenis     llst_const,
295b725ae77Skettenis     llst_unknown,
296b725ae77Skettenis     llst_max
297b725ae77Skettenis } Dbg_LLSymType;
298b725ae77Skettenis /* Since AIF images contain no type information for low-level symbols, this
299b725ae77Skettenis    classification is only a guess, and some symbols describing constants will
300b725ae77Skettenis    incorrectly be described as code or data.
301b725ae77Skettenis  */
302b725ae77Skettenis 
303b725ae77Skettenis typedef Dbg_Error Dbg_SymProc(
304b725ae77Skettenis     Dbg_MCState *state,
305b725ae77Skettenis     const char *symbol, Dbg_LLSymType symtype, ARMaddress value,
306b725ae77Skettenis     void *arg);
307b725ae77Skettenis 
308b725ae77Skettenis Dbg_Error Dbg_EnumerateLowLevelSymbols(
309b725ae77Skettenis     Dbg_MCState *state, const char *match, Dbg_SymProc *p,
310b725ae77Skettenis     void *arg);
311b725ae77Skettenis /* Call  p(name, value)  for each low level symbol in the tables of <state>
312b725ae77Skettenis    whose name matches the regular expression <match> (a NULL <match> matches
313b725ae77Skettenis    any name).  Symbols are enumerated in no particular order.
314b725ae77Skettenis  */
315b725ae77Skettenis 
316b725ae77Skettenis /*--------------------------------------------------------------------------*/
317b725ae77Skettenis 
318b725ae77Skettenis /* Functions are provided here to allow quick mass access to register values
319b725ae77Skettenis    for display.  There is no comparable need for quick mass update, so writing
320b725ae77Skettenis    should be via Assign().
321b725ae77Skettenis  */
322b725ae77Skettenis 
323b725ae77Skettenis typedef struct Dbg_RegSet {
324b725ae77Skettenis     ARMword
325b725ae77Skettenis         user[15],
326b725ae77Skettenis         pc,
327b725ae77Skettenis         psr,
328b725ae77Skettenis         fiq[7],
329b725ae77Skettenis         spsr_fiq,
330b725ae77Skettenis         irq[2],
331b725ae77Skettenis         spsr_irq,
332b725ae77Skettenis         svc[2],
333b725ae77Skettenis         spsr_svc,
334b725ae77Skettenis         abort[2],
335b725ae77Skettenis         spsr_abort,
336b725ae77Skettenis         undef[2],
337b725ae77Skettenis         spsr_undef;
338b725ae77Skettenis } Dbg_RegSet;
339b725ae77Skettenis 
340b725ae77Skettenis /* bits in the modemask argument for ReadRegisters */
341b725ae77Skettenis 
342b725ae77Skettenis #define Dbg_MM_User     1
343b725ae77Skettenis #define Dbg_MM_FIQ      2
344b725ae77Skettenis #define Dbg_MM_IRQ      4
345b725ae77Skettenis #define Dbg_MM_SVC      8
346b725ae77Skettenis #define Dbg_MM_Abort 0x10
347b725ae77Skettenis #define Dbg_MM_Undef 0x20
348b725ae77Skettenis #define Dbg_MM_System 0x40
349b725ae77Skettenis 
350b725ae77Skettenis Dbg_Error Dbg_ReadRegisters(Dbg_MCState *state, Dbg_RegSet *regs, int modemask);
351b725ae77Skettenis 
352b725ae77Skettenis Dbg_Error Dbg_WriteRegister(Dbg_MCState *state, int rno, int modemask, ARMword val);
353b725ae77Skettenis 
354b725ae77Skettenis int Dbg_StringToMode(const char *name);
355b725ae77Skettenis 
356b725ae77Skettenis int Dbg_ModeToModeMask(ARMword mode);
357b725ae77Skettenis 
358b725ae77Skettenis /* Some implementations of the FP instruction set keep FP values loaded into
359b725ae77Skettenis    registers in their unconverted format, converting only when necessary.
360b725ae77Skettenis    Some RDI implementations deliver these values uninterpreted.
361b725ae77Skettenis    (For the rest, register values will always have type F_Extended).
362b725ae77Skettenis  */
363b725ae77Skettenis 
364b725ae77Skettenis typedef enum { F_Single, F_Double, F_Extended, F_Packed, /* fpe340 values */
365b725ae77Skettenis                F_Internal,                               /* new fpe : mostly as extended */
366b725ae77Skettenis                F_None } Dbg_FPType;
367b725ae77Skettenis 
368b725ae77Skettenis typedef struct { ARMword w[3]; } Dbg_TargetExtendedVal;
369b725ae77Skettenis typedef struct { ARMword w[3]; } Dbg_TargetPackedVal;
370b725ae77Skettenis typedef struct { ARMword w[2]; } Dbg_TargetDoubleVal;
371b725ae77Skettenis typedef struct { ARMword w[1]; } Dbg_TargetFloatVal;
372b725ae77Skettenis 
373b725ae77Skettenis typedef union { Dbg_TargetExtendedVal e; Dbg_TargetPackedVal p;
374b725ae77Skettenis                 Dbg_TargetDoubleVal d; Dbg_TargetFloatVal f; } Dbg_TargetFPVal;
375b725ae77Skettenis 
376b725ae77Skettenis #define TargetSizeof_Extended 12
377b725ae77Skettenis #define TargetSizeof_Packed   12
378b725ae77Skettenis #define TargetSizeof_Double   8
379b725ae77Skettenis #define TargetSizeof_Float    4
380b725ae77Skettenis 
381b725ae77Skettenis typedef struct Dbg_FPRegVal {
382b725ae77Skettenis      Dbg_FPType type;
383b725ae77Skettenis      Dbg_TargetFPVal v;
384b725ae77Skettenis } Dbg_FPRegVal;
385b725ae77Skettenis 
386b725ae77Skettenis typedef struct Dbg_FPRegSet {
387b725ae77Skettenis     Dbg_FPRegVal f[8];
388b725ae77Skettenis     ARMword fpsr, fpcr;
389b725ae77Skettenis } Dbg_FPRegSet;
390b725ae77Skettenis 
391b725ae77Skettenis Dbg_Error Dbg_ReadFPRegisters(Dbg_MCState *state, Dbg_FPRegSet *regs);
392b725ae77Skettenis 
393b725ae77Skettenis Dbg_Error Dbg_WriteFPRegisters(Dbg_MCState *state, int32 mask, Dbg_FPRegSet *regs);
394b725ae77Skettenis 
395b725ae77Skettenis Dbg_Error Dbg_FPRegToDouble(DbleBin *d, Dbg_FPRegVal const *f);
396b725ae77Skettenis /* Converts from a FP register value (in any format) to a double with
397b725ae77Skettenis    approximately the same value (or returns Dbg_Err_Overflow)
398b725ae77Skettenis  */
399b725ae77Skettenis 
400b725ae77Skettenis void Dbg_DoubleToFPReg(Dbg_FPRegVal *f, DbleBin const *d);
401b725ae77Skettenis /* Converts the double <d> to a Dbg_FPRegVal with type F_Extended */
402b725ae77Skettenis 
403b725ae77Skettenis /*--------------------------------------------------------------------------*/
404b725ae77Skettenis 
405b725ae77Skettenis #include "dbg_cp.h"
406b725ae77Skettenis 
407b725ae77Skettenis Dbg_Error Dbg_DescribeCoPro(Dbg_MCState *state, int cpnum, Dbg_CoProDesc *p);
408b725ae77Skettenis 
409b725ae77Skettenis Dbg_Error Dbg_DescribeCoPro_RDI(Dbg_MCState *state, int cpnum, Dbg_CoProDesc *p);
410b725ae77Skettenis 
411b725ae77Skettenis Dbg_Error Dbg_ReadCPRegisters(Dbg_MCState *state, int cpnum, ARMword *regs);
412b725ae77Skettenis 
413b725ae77Skettenis Dbg_Error Dbg_WriteCPRegisters(Dbg_MCState *state, int cpnum, int32 mask, ARMword *regs);
414b725ae77Skettenis 
415b725ae77Skettenis /*--------------------------------------------------------------------------*/
416b725ae77Skettenis 
417b725ae77Skettenis Dbg_Error Dbg_ReadWords(
418b725ae77Skettenis     Dbg_MCState *state,
419b725ae77Skettenis     ARMword *words, ARMaddress addr, unsigned count);
420b725ae77Skettenis /* Reads a number of (32-bit) words from target store.  The values are in host
421b725ae77Skettenis    byte order; if they are also to be interpreted as bytes Dbg_SwapByteOrder()
422b725ae77Skettenis    must be called to convert to target byte order.
423b725ae77Skettenis  */
424b725ae77Skettenis 
425b725ae77Skettenis Dbg_Error Dbg_WriteWords(
426b725ae77Skettenis     Dbg_MCState *state,
427b725ae77Skettenis     ARMaddress addr, const ARMword *words, unsigned count);
428b725ae77Skettenis /* Writes a number of (32-bit) words to target store.  The values are in host
429b725ae77Skettenis    byte order (if what is being written is actually a byte string it must be
430b725ae77Skettenis    converted by Dbg_SwapByteOrder()).
431b725ae77Skettenis  */
432b725ae77Skettenis 
433b725ae77Skettenis Dbg_Error Dbg_ReadHalf(Dbg_MCState *state, ARMhword *val, ARMaddress addr);
434b725ae77Skettenis Dbg_Error Dbg_WriteHalf(Dbg_MCState *state, ARMaddress addr, ARMword val);
435b725ae77Skettenis 
436b725ae77Skettenis Dbg_Error Dbg_ReadBytes(Dbg_MCState *state, Dbg_Byte *val, ARMaddress addr, unsigned count);
437b725ae77Skettenis Dbg_Error Dbg_WriteBytes(Dbg_MCState *state, ARMaddress addr, const Dbg_Byte *val, unsigned count);
438b725ae77Skettenis 
439b725ae77Skettenis void Dbg_HostWords(Dbg_MCState *state, ARMword *words, unsigned wordcount);
440b725ae77Skettenis /* (A noop unless host and target bytesexes differ) */
441b725ae77Skettenis 
442b725ae77Skettenis ARMword Dbg_HostWord(Dbg_MCState *state, ARMword v);
443b725ae77Skettenis 
444b725ae77Skettenis ARMhword Dbg_HostHalf(Dbg_MCState *state, ARMword v);
445b725ae77Skettenis 
446b725ae77Skettenis /*--------------------------------------------------------------------------*/
447b725ae77Skettenis 
448b725ae77Skettenis /* Types describing various aspects of position within code.
449b725ae77Skettenis    There are rather a lot of these, in the interests of describing precisely
450b725ae77Skettenis    what fields must be present (rather than having a single type with many
451b725ae77Skettenis    fields which may or may not be valid according to context).
452b725ae77Skettenis  */
453b725ae77Skettenis 
454b725ae77Skettenis typedef struct Dbg_LLPos {
455b725ae77Skettenis     Dbg_SymTable *st;
456b725ae77Skettenis     char *llsym;
457b725ae77Skettenis     ARMaddress offset;
458b725ae77Skettenis } Dbg_LLPos;
459b725ae77Skettenis 
460b725ae77Skettenis typedef struct Dbg_File {
461b725ae77Skettenis     Dbg_SymTable *st;
462b725ae77Skettenis     char *file;
463b725ae77Skettenis } Dbg_File;
464b725ae77Skettenis 
465b725ae77Skettenis typedef struct Dbg_Line {
466b725ae77Skettenis     unsigned32 line;      /* linenumber in the file */
467b725ae77Skettenis     unsigned16 statement, /* within the line (1-based) */
468b725ae77Skettenis                charpos;   /* ditto */
469b725ae77Skettenis } Dbg_Line;
470b725ae77Skettenis /* As an output value from toolbox functions, both statement and charpos are set
471b725ae77Skettenis    if the version of the debugger tables for the section concerned permits.
472b725ae77Skettenis    On input, <charpos> is used only if <statement> is 0 (in which case, if
473b725ae77Skettenis    <charpos> is non-0, Dbg_Err_DbgTableVersion is returned if the version of
474b725ae77Skettenis    the debugger tables concerned is too early.
475b725ae77Skettenis  */
476b725ae77Skettenis 
477b725ae77Skettenis typedef struct Dbg_FilePos {
478b725ae77Skettenis     Dbg_File f;
479b725ae77Skettenis     Dbg_Line line;
480b725ae77Skettenis } Dbg_FilePos;
481b725ae77Skettenis 
482b725ae77Skettenis typedef struct Dbg_ProcDesc {
483b725ae77Skettenis     Dbg_File f;
484b725ae77Skettenis     char *name;
485b725ae77Skettenis } Dbg_ProcDesc;
486b725ae77Skettenis 
487b725ae77Skettenis typedef struct Dbg_ProcPos {
488b725ae77Skettenis     Dbg_ProcDesc p;
489b725ae77Skettenis     Dbg_Line line;
490b725ae77Skettenis } Dbg_ProcPos;
491b725ae77Skettenis 
492b725ae77Skettenis /* Support for conversions between position representations */
493b725ae77Skettenis 
494b725ae77Skettenis Dbg_Error Dbg_ProcDescToLine(Dbg_MCState *state, Dbg_ProcDesc *proc, Dbg_Line *line);
495b725ae77Skettenis /* If proc->f.file is null (and there is just one function proc->name), it is
496b725ae77Skettenis    updated to point to the name of the file containing (the start of)
497b725ae77Skettenis    proc->name.
498b725ae77Skettenis  */
499b725ae77Skettenis 
500b725ae77Skettenis Dbg_Error Dbg_FilePosToProc(Dbg_MCState *state, const Dbg_FilePos *pos, char **procname);
501b725ae77Skettenis 
502b725ae77Skettenis /* Conversions from position representations to and from code addresses */
503b725ae77Skettenis 
504b725ae77Skettenis Dbg_Error Dbg_AddressToProcPos(
505b725ae77Skettenis     Dbg_MCState *state, ARMaddress addr,
506b725ae77Skettenis     Dbg_ProcPos *pos);
507b725ae77Skettenis Dbg_Error Dbg_AddressToLLPos(
508b725ae77Skettenis     Dbg_MCState *state, ARMaddress addr,
509b725ae77Skettenis     Dbg_LLPos *pos, Dbg_LLSymType *res_type, int system_names);
510b725ae77Skettenis 
511b725ae77Skettenis Dbg_Error Dbg_ProcPosToAddress(
512b725ae77Skettenis     Dbg_MCState *state, const Dbg_ProcPos *pos,
513b725ae77Skettenis     ARMaddress *res);
514b725ae77Skettenis Dbg_Error Dbg_LLPosToAddress(
515b725ae77Skettenis     Dbg_MCState *state, const Dbg_LLPos *pos,
516b725ae77Skettenis     ARMaddress *res);
517b725ae77Skettenis 
518b725ae77Skettenis typedef struct {
519b725ae77Skettenis     ARMaddress start, end;
520b725ae77Skettenis } Dbg_AddressRange;
521b725ae77Skettenis 
522b725ae77Skettenis typedef Dbg_Error Dbg_AddressRangeProc(void *arg, int32 first, int32 last, Dbg_AddressRange const *range);
523b725ae77Skettenis 
524b725ae77Skettenis Dbg_Error Dbg_MapAddressRangesForFileRange(
525b725ae77Skettenis     Dbg_MCState *state,
526b725ae77Skettenis     Dbg_SymTable *st, const char *f, int32 first, int32 last, Dbg_AddressRangeProc *p, void *arg);
527b725ae77Skettenis 
528b725ae77Skettenis typedef struct Dbg_Environment Dbg_Environment;
529b725ae77Skettenis /* A Dbg_Environment describes the context required to make sense of a variable
530b725ae77Skettenis    name and access its value.  Its format is not revealed.  Dbg_Environment
531b725ae77Skettenis    values are allocated by Dbg_NewEnvironment() and discarded by
532b725ae77Skettenis    Dbg_DeleteEnvironment().
533b725ae77Skettenis  */
534b725ae77Skettenis 
535b725ae77Skettenis Dbg_Environment *Dbg_NewEnvironment(Dbg_MCState *state);
536b725ae77Skettenis void Dbg_DeleteEnvironment(Dbg_MCState *state, Dbg_Environment *env);
537b725ae77Skettenis 
538b725ae77Skettenis Dbg_Error Dbg_StringToEnv(
539b725ae77Skettenis     Dbg_MCState *state, char *str, Dbg_Environment *resenv,
540b725ae77Skettenis     int forcontext, Dbg_Environment const *curenv);
541b725ae77Skettenis 
542b725ae77Skettenis Dbg_Error Dbg_ProcPosToEnvironment(
543b725ae77Skettenis     Dbg_MCState *state, const Dbg_ProcPos *pos, int activation,
544b725ae77Skettenis     const Dbg_Environment *current, Dbg_Environment *res);
545b725ae77Skettenis 
546b725ae77Skettenis /* Conversion from a position representation to an Dbg_Environment (as required
547b725ae77Skettenis    to access variable values).  Only a Dbg_ProcPos argument here; other
548b725ae77Skettenis    representations need to be converted first.
549b725ae77Skettenis 
550b725ae77Skettenis    Returns <res> describing the <activation>th instance of the function
551b725ae77Skettenis    described by <pos>, up from the stack base if <activation> is negative,
552b725ae77Skettenis    else down from <current>.
553b725ae77Skettenis    If this function returns Dbg_Err_ActivationNotPresent, the result
554b725ae77Skettenis    Dbg_Environment is still valid for accessing non-auto variables.
555b725ae77Skettenis  */
556b725ae77Skettenis 
557b725ae77Skettenis typedef struct Dbg_DeclSpec Dbg_DeclSpec;
558b725ae77Skettenis 
559b725ae77Skettenis Dbg_Error Dbg_EnvToProcItem(
560b725ae77Skettenis     Dbg_MCState *state, Dbg_Environment const *env, Dbg_DeclSpec *proc);
561b725ae77Skettenis 
562b725ae77Skettenis Dbg_Error Dbg_ContainingEnvironment(
563b725ae77Skettenis     Dbg_MCState *state, const Dbg_Environment *context, Dbg_Environment *res);
564b725ae77Skettenis /* Set <res> to describe the containing function, file if <context> is within
565b725ae77Skettenis    a top-level function (or error if <context> already describes a file).
566b725ae77Skettenis  */
567b725ae77Skettenis 
568b725ae77Skettenis /*--------------------------------------------------------------------------*/
569b725ae77Skettenis 
570b725ae77Skettenis /* ASD debug table pointers are not by themselves sufficient description,
571b725ae77Skettenis    since there's an implied section context.  Hence the DeclSpec and TypeSpec
572b725ae77Skettenis    structures.
573b725ae77Skettenis  */
574b725ae77Skettenis 
575b725ae77Skettenis 
576b725ae77Skettenis #ifndef Dbg_TypeSpec_Defined
577b725ae77Skettenis 
578b725ae77Skettenis struct Dbg_DeclSpec { void *a; };
579b725ae77Skettenis 
580b725ae77Skettenis #ifdef CALLABLE_COMPILER
581b725ae77Skettenis typedef void *Dbg_TypeSpec;
582b725ae77Skettenis 
583b725ae77Skettenis /* The intention here is to give an alternative definition for Dbg_BasicType
584b725ae77Skettenis    which follows.
585b725ae77Skettenis  */
586b725ae77Skettenis 
587b725ae77Skettenis #define Dbg_T_Void      xDbg_T_Void
588b725ae77Skettenis #define Dbg_T_Bool      xDbg_T_Bool
589b725ae77Skettenis #define Dbg_T_SByte     xDbg_T_SByte
590b725ae77Skettenis #define Dbg_T_SHalf     xDbg_T_Half
591b725ae77Skettenis #define Dbg_T_SWord     xDbg_T_SWord
592b725ae77Skettenis #define Dbg_T_UByte     xDbg_T_UByte
593b725ae77Skettenis #define Dbg_T_UHalf     xDbg_T_UHalf
594b725ae77Skettenis #define Dbg_T_UWord     xDbg_T_UWord
595b725ae77Skettenis #define Dbg_T_Float     xDbg_T_Float
596b725ae77Skettenis #define Dbg_T_Double    xDbg_T_Double
597b725ae77Skettenis #define Dbg_T_LDouble   xDbg_T_LDouble
598b725ae77Skettenis #define Dbg_T_Complex   xDbg_T_Complex
599b725ae77Skettenis #define Dbg_T_DComplex  xDbg_T_DComplex
600b725ae77Skettenis #define Dbg_T_String    xDbg_T_String
601b725ae77Skettenis #define Dbg_T_Function  xDbg_T_Function
602b725ae77Skettenis 
603b725ae77Skettenis #define Dbg_BasicType   xDbg_BaiscType
604b725ae77Skettenis #define Dbg_PrimitiveTypeToTypeSpec xDbg_PrimitiveTypeToTypeSpec
605b725ae77Skettenis 
606b725ae77Skettenis #else
607b725ae77Skettenis /* We want a Dbg_TypeSpec to be a an opaque type, but of known size (so the
608b725ae77Skettenis    toolbox's clients can allocate the store to hold one); unfortunately, we
609b725ae77Skettenis    can do this only by having one definition for the toolbox's clients and
610b725ae77Skettenis    one (elsewhere) for the toolbox itself.
611b725ae77Skettenis  */
612b725ae77Skettenis 
613b725ae77Skettenis typedef struct Dbg_TypeSpec Dbg_TypeSpec;
614b725ae77Skettenis struct Dbg_TypeSpec { void *a; int32 b; };
615b725ae77Skettenis #endif /* CALLABLE_COMPILER */
616b725ae77Skettenis 
617b725ae77Skettenis typedef enum {
618b725ae77Skettenis     Dbg_T_Void,
619b725ae77Skettenis 
620b725ae77Skettenis     Dbg_T_Bool,
621b725ae77Skettenis 
622b725ae77Skettenis     Dbg_T_SByte,
623b725ae77Skettenis     Dbg_T_SHalf,
624b725ae77Skettenis     Dbg_T_SWord,
625b725ae77Skettenis 
626b725ae77Skettenis     Dbg_T_UByte,
627b725ae77Skettenis     Dbg_T_UHalf,
628b725ae77Skettenis     Dbg_T_UWord,
629b725ae77Skettenis 
630b725ae77Skettenis     Dbg_T_Float,
631b725ae77Skettenis     Dbg_T_Double,
632b725ae77Skettenis     Dbg_T_LDouble,
633b725ae77Skettenis 
634b725ae77Skettenis     Dbg_T_Complex,
635b725ae77Skettenis     Dbg_T_DComplex,
636b725ae77Skettenis 
637b725ae77Skettenis     Dbg_T_String,
638b725ae77Skettenis 
639b725ae77Skettenis     Dbg_T_Function
640b725ae77Skettenis } Dbg_BasicType;
641b725ae77Skettenis 
642b725ae77Skettenis #endif
643b725ae77Skettenis 
644b725ae77Skettenis void Dbg_PrimitiveTypeToTypeSpec(Dbg_TypeSpec *ts, Dbg_BasicType t);
645b725ae77Skettenis 
646b725ae77Skettenis bool Dbg_TypeIsIntegral(Dbg_TypeSpec const *ts);
647b725ae77Skettenis 
648b725ae77Skettenis bool Dbg_TypeIsPointer(Dbg_TypeSpec const *ts);
649b725ae77Skettenis 
650b725ae77Skettenis bool Dbg_TypeIsFunction(Dbg_TypeSpec const *ts);
651b725ae77Skettenis 
652b725ae77Skettenis bool Dbg_PruneType(Dbg_TypeSpec *tsres, Dbg_TypeSpec const *ts);
653b725ae77Skettenis /* Return to tsres a version of ts which has been pruned by the removal of all
654b725ae77Skettenis    toplevel typedefs. Result is YES if the result has changed.
655b725ae77Skettenis  */
656b725ae77Skettenis 
657b725ae77Skettenis typedef Dbg_Error Dbg_FileProc(Dbg_MCState *state, const char *name, const Dbg_DeclSpec *procdef, void *arg);
658b725ae77Skettenis 
659b725ae77Skettenis Dbg_Error Dbg_EnumerateFiles(Dbg_MCState *state, Dbg_SymTable *st, Dbg_FileProc *p, void *arg);
660b725ae77Skettenis /* The top level for a high level enumerate.  Lower levels are performed by
661b725ae77Skettenis    EnumerateDeclarations (below).
662b725ae77Skettenis  */
663b725ae77Skettenis 
664b725ae77Skettenis typedef enum {
665b725ae77Skettenis     ds_Invalid,
666b725ae77Skettenis     ds_Type,
667b725ae77Skettenis     ds_Var,
668b725ae77Skettenis     ds_Proc,
669b725ae77Skettenis     ds_Enum,
670b725ae77Skettenis     ds_Function,
671b725ae77Skettenis     ds_Label
672b725ae77Skettenis } Dbg_DeclSort;
673b725ae77Skettenis 
674b725ae77Skettenis Dbg_DeclSort Dbg_SortOfDeclSpec(Dbg_DeclSpec const *decl);
675b725ae77Skettenis 
676b725ae77Skettenis char *Dbg_NameOfDeclSpec(Dbg_DeclSpec const *decl);
677b725ae77Skettenis 
678b725ae77Skettenis Dbg_TypeSpec Dbg_TypeSpecOfDeclSpec(Dbg_DeclSpec const *decl);
679b725ae77Skettenis 
680b725ae77Skettenis typedef enum {
681b725ae77Skettenis     cs_None,
682b725ae77Skettenis     cs_Extern,
683b725ae77Skettenis     cs_Static,
684b725ae77Skettenis     cs_Auto,
685b725ae77Skettenis     cs_Reg,
686b725ae77Skettenis     cs_Var,
687b725ae77Skettenis     cs_Farg,
688b725ae77Skettenis     cs_Fcarg,
689b725ae77Skettenis     cs_Local,
690b725ae77Skettenis     cs_Filtered,
691b725ae77Skettenis     cs_Globalreg
692b725ae77Skettenis } Dbg_StgClass;
693b725ae77Skettenis 
694b725ae77Skettenis Dbg_StgClass Dbg_StgClassOfDeclSpec(Dbg_DeclSpec const *decl);
695b725ae77Skettenis 
696b725ae77Skettenis bool Dbg_VarsAtSameAddress(Dbg_DeclSpec const *d1, Dbg_DeclSpec const *d2);
697b725ae77Skettenis 
698b725ae77Skettenis bool Dbg_VarsDecribedForDeclSpec(Dbg_DeclSpec const *decl);
699b725ae77Skettenis 
700b725ae77Skettenis int Dbg_ArgCountOfDeclSpec(Dbg_DeclSpec const *decl);
701b725ae77Skettenis 
702b725ae77Skettenis typedef struct Dbg_DComplex { DbleBin r, i; } Dbg_DComplex;
703b725ae77Skettenis 
704b725ae77Skettenis typedef union Dbg_ConstantVal {
705b725ae77Skettenis     int32 l;
706b725ae77Skettenis     unsigned32 u;
707b725ae77Skettenis     DbleBin d;
708b725ae77Skettenis     Dbg_DComplex fc;
709b725ae77Skettenis     ARMaddress a;
710b725ae77Skettenis     char *s;
711b725ae77Skettenis } Dbg_ConstantVal;
712b725ae77Skettenis 
713b725ae77Skettenis typedef struct Dbg_Constant {
714b725ae77Skettenis     Dbg_TypeSpec type;
715b725ae77Skettenis     Dbg_ConstantVal val;
716b725ae77Skettenis } Dbg_Constant;
717b725ae77Skettenis 
718b725ae77Skettenis typedef enum Dbg_ValueSort {
719b725ae77Skettenis     vs_register,
720b725ae77Skettenis     vs_store,
721b725ae77Skettenis     vs_constant,
722b725ae77Skettenis     vs_local,
723b725ae77Skettenis     vs_filtered,
724b725ae77Skettenis     vs_none,
725b725ae77Skettenis     vs_error
726b725ae77Skettenis } Dbg_ValueSort;
727b725ae77Skettenis 
728b725ae77Skettenis /* vs_local allows the use of symbol table entries to describe entities within
729b725ae77Skettenis    the debugger's own address space, accessed in the same way as target
730b725ae77Skettenis    variables.
731b725ae77Skettenis    vs_filtered describes entities which may be read or written only via an
732b725ae77Skettenis    access function (eg r15)
733b725ae77Skettenis  */
734b725ae77Skettenis 
735b725ae77Skettenis #define fpr_base 16
736b725ae77Skettenis /* There's only one register ValueSort (reflecting asd table StgClass);
737b725ae77Skettenis    fp register n is encoded as register n+fpr_base.
738b725ae77Skettenis  */
739b725ae77Skettenis 
740b725ae77Skettenis typedef struct Dbg_Value Dbg_Value;
741b725ae77Skettenis 
742b725ae77Skettenis typedef Dbg_Error Dbg_AccessFn(Dbg_MCState *state, int write, Dbg_Value *self, Dbg_Constant *c);
743b725ae77Skettenis /* <write> == 0: read a vs_filtered value, updating the value self.
744b725ae77Skettenis    <write> == 1: update a vs_filtered value, with the value described by c.
745b725ae77Skettenis    <self> allows use of the same Dbg_AccessFn for several different entities
746b725ae77Skettenis    (using different val.f.id fields).
747b725ae77Skettenis  */
748b725ae77Skettenis 
749b725ae77Skettenis typedef Dbg_Error Dbg_FormatFn(int decode, char *b, ARMword *valp, void *formatarg);
750b725ae77Skettenis 
751b725ae77Skettenis typedef struct { Dbg_AccessFn *f; int id; } Dbg_AccessFnRec;
752b725ae77Skettenis 
753b725ae77Skettenis struct Dbg_Value {
754b725ae77Skettenis     Dbg_TypeSpec type;
755b725ae77Skettenis     Dbg_ValueSort sort;
756b725ae77Skettenis     Dbg_FormatFn *formatp;
757b725ae77Skettenis     void *formatarg;
758b725ae77Skettenis     int f77csize;
759b725ae77Skettenis     union {
760b725ae77Skettenis         struct { int no; ARMaddress frame; } r;
761b725ae77Skettenis         ARMaddress ptr;
762b725ae77Skettenis         Dbg_ConstantVal c;
763b725ae77Skettenis         void *localp;
764b725ae77Skettenis         Dbg_AccessFnRec f;
765b725ae77Skettenis         Dbg_Error err;
766b725ae77Skettenis     } val;
767b725ae77Skettenis };
768b725ae77Skettenis 
769b725ae77Skettenis Dbg_Error Dbg_AddLLSymbol(Dbg_SymTable *st, char const *name, Dbg_LLSymType type, ARMword val);
770b725ae77Skettenis 
771b725ae77Skettenis Dbg_Error Dbg_AddSymbol(Dbg_SymTable *st, char const *name, Dbg_Value const *val);
772b725ae77Skettenis 
773b725ae77Skettenis typedef struct Dbg_DeclSpecF {
774b725ae77Skettenis   Dbg_DeclSpec decl;
775b725ae77Skettenis   Dbg_FormatFn *formatp;
776b725ae77Skettenis   void *formatarg;
777b725ae77Skettenis } Dbg_DeclSpecF;
778b725ae77Skettenis 
779b725ae77Skettenis typedef Dbg_Error Dbg_DeclProc(Dbg_MCState *state, Dbg_Environment const *context,
780b725ae77Skettenis                        Dbg_DeclSpecF const *var, Dbg_DeclSort sort, int masked,
781b725ae77Skettenis                        void *arg);
782b725ae77Skettenis 
783b725ae77Skettenis Dbg_Error Dbg_EnumerateDeclarations(Dbg_MCState *state, Dbg_Environment const *context,
784b725ae77Skettenis                             Dbg_DeclProc *p, void *arg);
785b725ae77Skettenis /* call p once for every declaration local to the function described by
786b725ae77Skettenis    <context> (or file if <context> describes a place outside a function).
787b725ae77Skettenis    p's argument <masked> is true if the variable is not visible, thanks to
788b725ae77Skettenis    a declaration in an inner scope.
789b725ae77Skettenis  */
790b725ae77Skettenis 
791b725ae77Skettenis Dbg_Error Dbg_ValueOfVar(Dbg_MCState *state, const Dbg_Environment *context,
792b725ae77Skettenis                  const Dbg_DeclSpec *var, Dbg_Value *val);
793b725ae77Skettenis /* Different from Dbg_EvalExpr() in that the thing being evaluated is described
794b725ae77Skettenis    by a Dbg_DeclSpec (which must be for a variable), rather than a string
795b725ae77Skettenis    needing to be decoded and associated with a symbol-table item.  Intended to
796b725ae77Skettenis    be called from a Dbg_DeclProc called from Dbg_EnumerateDeclarations.
797b725ae77Skettenis  */
798b725ae77Skettenis 
799b725ae77Skettenis Dbg_Error Dbg_EvalExpr(Dbg_MCState *state, Dbg_Environment const *context,
800b725ae77Skettenis                char const *expr, int flags, Dbg_Value *val);
801b725ae77Skettenis 
802b725ae77Skettenis Dbg_Error Dbg_EvalExpr_ep(Dbg_MCState *state, Dbg_Environment const *context,
803b725ae77Skettenis                   char const *expr, char **exprend, int flags, Dbg_Value *val);
804b725ae77Skettenis 
805b725ae77Skettenis /* Both Dbg_ValueOfVar and Dbg_EvalExpr mostly deliver a value still containing
806b725ae77Skettenis    an indirection (since it may be wanted as the lhs of an assignment)
807b725ae77Skettenis  */
808b725ae77Skettenis 
809b725ae77Skettenis void Dbg_RealLocation(Dbg_MCState *state, Dbg_Value *val);
810b725ae77Skettenis /* If val describes a register, this may really be a register, or a place on
811b725ae77Skettenis    the stack where the register's value is saved. In the latter case, val
812b725ae77Skettenis    is altered to describe the save place. (In all others, it remains
813b725ae77Skettenis    unchanged).
814b725ae77Skettenis  */
815b725ae77Skettenis 
816b725ae77Skettenis Dbg_Error Dbg_DereferenceValue(Dbg_MCState *state, const Dbg_Value *value, Dbg_Constant *c);
817b725ae77Skettenis /* This fails if <value> describes a structure or array, returning
818b725ae77Skettenis    Dbg_Err_TypeNotSimple
819b725ae77Skettenis  */
820b725ae77Skettenis 
821b725ae77Skettenis typedef struct Dbg_Expr Dbg_Expr;
822b725ae77Skettenis /* The result of parsing an expression in an environment: its structure is not
823b725ae77Skettenis    revealed.  (Clients may wish to parse just once an expression which may be
824b725ae77Skettenis    evaluated often).  In support of which, the following two functions partition
825b725ae77Skettenis    the work of Dbg_EvalExpr().
826b725ae77Skettenis  */
827b725ae77Skettenis 
828b725ae77Skettenis #define Dbg_exfl_heap 1    /* allocate Expr on the heap (FreeExpr must then be
829b725ae77Skettenis                               called to discard it).  Otherwise, it goes in a
830b725ae77Skettenis                               place overwritten by the next call to ParseExpr
831b725ae77Skettenis                               or EvalExpr
832b725ae77Skettenis                             */
833b725ae77Skettenis #define Dbg_exfl_needassign 2
834b725ae77Skettenis #define Dbg_exfl_lowlevel   4
835b725ae77Skettenis 
836b725ae77Skettenis int Dbg_SetInputRadix(Dbg_MCState *state, int radix);
837b725ae77Skettenis char *Dbg_SetDefaultIntFormat(Dbg_MCState *state, char *format);
838b725ae77Skettenis 
839b725ae77Skettenis Dbg_Error Dbg_ParseExpr(
840b725ae77Skettenis     Dbg_MCState *state, Dbg_Environment const *env, char *string,
841b725ae77Skettenis     char **end, Dbg_Expr **res, int flags);
842b725ae77Skettenis /* Just parse the argument string, returning a pointer to a parsed expression
843b725ae77Skettenis    and a pointer to the first non-white space character in the input string
844b725ae77Skettenis    which is not part of the parsed expression. (If macro expansion has taken
845b725ae77Skettenis    place, the returned pointer will not be into the argument string at all,
846b725ae77Skettenis    rather into the expanded version of it).
847b725ae77Skettenis  */
848b725ae77Skettenis 
849b725ae77Skettenis Dbg_Error Dbg_ParseExprCheckEnd(
850b725ae77Skettenis     Dbg_MCState *state, Dbg_Environment const *env, char *string,
851b725ae77Skettenis     Dbg_Expr **res, int flags);
852b725ae77Skettenis /* As Dbg_ParseExpr, but the parsed expression is required completely to fill
853b725ae77Skettenis    the argument string (apart possibly for trailing whitespace), and an error
854b725ae77Skettenis    is returned if it does not.
855b725ae77Skettenis  */
856b725ae77Skettenis 
857b725ae77Skettenis Dbg_Error Dbg_ParsedExprToValue(
858b725ae77Skettenis     Dbg_MCState *state, const Dbg_Environment *env, Dbg_Expr *expr, Dbg_Value *v);
859b725ae77Skettenis 
860b725ae77Skettenis Dbg_Error Dbg_ReadDecl(
861b725ae77Skettenis     Dbg_MCState *state, Dbg_Environment const *env, char *string,
862b725ae77Skettenis     Dbg_TypeSpec *p, char **varp, int flags);
863b725ae77Skettenis /* Read a variable declaration, returing a description of the type of the
864b725ae77Skettenis    variable to p, and a pointer to its name to varp.
865b725ae77Skettenis  */
866b725ae77Skettenis 
867b725ae77Skettenis bool Dbg_IsCastToArrayType(Dbg_MCState *state, Dbg_Expr *expr);
868b725ae77Skettenis 
869b725ae77Skettenis void Dbg_FreeExpr(Dbg_Expr *expr);
870b725ae77Skettenis 
871b725ae77Skettenis Dbg_Error Dbg_CopyType(Dbg_TypeSpec *tdest, Dbg_TypeSpec const *tsource);
872b725ae77Skettenis Dbg_Error Dbg_FreeCopiedType(Dbg_TypeSpec *ts);
873b725ae77Skettenis 
874b725ae77Skettenis Dbg_Error Dbg_TypeOfExpr(Dbg_MCState *state, Dbg_Expr *tree, Dbg_TypeSpec *restype);
875b725ae77Skettenis 
876b725ae77Skettenis Dbg_Error Dbg_ExprToVar(const Dbg_Expr *expr, Dbg_DeclSpec *var, Dbg_Environment *env);
877b725ae77Skettenis 
878b725ae77Skettenis Dbg_Error Dbg_Assign(Dbg_MCState *state, const Dbg_Value *lv, const Dbg_Value *rv);
879b725ae77Skettenis 
880b725ae77Skettenis typedef enum Dbg_TypeSort {
881b725ae77Skettenis   ts_simple,
882b725ae77Skettenis   ts_union,
883b725ae77Skettenis   ts_struct,
884b725ae77Skettenis   ts_array
885b725ae77Skettenis } Dbg_TypeSort;
886b725ae77Skettenis 
887b725ae77Skettenis Dbg_TypeSort Dbg_TypeSortOfValue(Dbg_MCState *state, const Dbg_Value *val, int *fieldcount);
888b725ae77Skettenis 
889b725ae77Skettenis Dbg_Error Dbg_TypeToChars(const Dbg_TypeSpec *var, Dbg_BufDesc *buf);
890b725ae77Skettenis 
891b725ae77Skettenis Dbg_Error Dbg_TypeSize(Dbg_MCState *state, const Dbg_TypeSpec *type, unsigned32 *res);
892b725ae77Skettenis 
893b725ae77Skettenis typedef int Dbg_ValToChars_cb(Dbg_MCState *state, Dbg_Value *subval, const char *fieldname,
894b725ae77Skettenis                           Dbg_BufDesc *buf, void *arg);
895b725ae77Skettenis 
896b725ae77Skettenis Dbg_Error Dbg_ValToChars(Dbg_MCState *state, Dbg_Value *val, int base,
897b725ae77Skettenis                  Dbg_ValToChars_cb *cb, void *arg,
898b725ae77Skettenis                  const char *form, Dbg_BufDesc *buf);
899b725ae77Skettenis /*
900b725ae77Skettenis    <base> is used for (any size) integer values.
901b725ae77Skettenis    If <val> is of an array or structure type, <cb> is called for each element,
902b725ae77Skettenis    with <arg> as its last parameter, and <subbuf> describing the space remaining
903b725ae77Skettenis    in <buf>.  If <cb> returns 0, conversion ceases.
904b725ae77Skettenis  */
905b725ae77Skettenis 
906b725ae77Skettenis Dbg_Error Dbg_NthElement(
907b725ae77Skettenis     Dbg_MCState *state,
908b725ae77Skettenis     const Dbg_Value *val, unsigned32 n, char **fieldname, Dbg_Value *subval);
909b725ae77Skettenis 
910b725ae77Skettenis typedef Dbg_Error Dbg_HistoryProc(void *, int, Dbg_Value *);
911b725ae77Skettenis 
912b725ae77Skettenis Dbg_Error Dbg_RegisterHistoryProc(Dbg_MCState *state, Dbg_HistoryProc *p, void *arg);
913b725ae77Skettenis 
914b725ae77Skettenis typedef enum {
915b725ae77Skettenis   ls_cpu,
916b725ae77Skettenis   ls_store,
917b725ae77Skettenis   ls_copro,
918b725ae77Skettenis   ls_local,
919b725ae77Skettenis   ls_filtered
920b725ae77Skettenis } Dbg_LocSort;
921b725ae77Skettenis 
922b725ae77Skettenis typedef struct {
923b725ae77Skettenis   Dbg_LocSort sort;
924b725ae77Skettenis   union {
925b725ae77Skettenis     struct { ARMaddress addr, size; } store;
926b725ae77Skettenis     struct { int modemask; int r; } cpu;
927b725ae77Skettenis     struct { int no; int r; } cp;
928b725ae77Skettenis     void *localp;
929b725ae77Skettenis     Dbg_AccessFnRec f;
930b725ae77Skettenis   } loc;
931b725ae77Skettenis } Dbg_Loc;
932b725ae77Skettenis 
933b725ae77Skettenis typedef Dbg_Error Dbg_ObjectWriteProc(Dbg_MCState *state, Dbg_Loc const *loc);
934b725ae77Skettenis Dbg_Error Dbg_OnObjectWrite(Dbg_MCState *state, Dbg_ObjectWriteProc *p);
935b725ae77Skettenis /* Register function to be called back whenever the toolbox has written to any
936b725ae77Skettenis  * object accessible by the debuggee (or to local variables belonging to a
937b725ae77Skettenis  * toolbox client). The write has already been done.
938b725ae77Skettenis  * (To allow multiple toolbox clients to coexist).
939b725ae77Skettenis  */
940b725ae77Skettenis 
941b725ae77Skettenis Dbg_Error Dbg_ObjectWritten(Dbg_MCState *state, Dbg_Loc const *loc);
942b725ae77Skettenis 
943b725ae77Skettenis /*--------------------------------------------------------------------------*/
944b725ae77Skettenis 
945b725ae77Skettenis /* Control of target program execution.
946b725ae77Skettenis    Currently, only synchronous operation is provided.
947b725ae77Skettenis    Execution could possibly be asynchronous where the target is a seperate
948b725ae77Skettenis    processor, but is necessarily synchronous if the target is Armulator.
949b725ae77Skettenis    Unfortunately, this may require modification to the RDI implementation
950b725ae77Skettenis    if multitasking is required but the the host system provides it only
951b725ae77Skettenis    cooperatively, or if there is no system-provided way to generate SIGINT.
952b725ae77Skettenis  */
953b725ae77Skettenis 
954b725ae77Skettenis Dbg_Error Dbg_SetCommandline(Dbg_MCState *state, const char *args);
955b725ae77Skettenis /* Set the argument string to the concatenation of the name of the most
956b725ae77Skettenis    recently loaded image and args.
957b725ae77Skettenis  */
958b725ae77Skettenis 
959b725ae77Skettenis typedef enum Dbg_ProgramState {
960b725ae77Skettenis     ps_notstarted,
961b725ae77Skettenis     /* Normal ways of stopping */
962b725ae77Skettenis     ps_atbreak, ps_atwatch, ps_stepdone,
963b725ae77Skettenis     ps_interrupted,
964b725ae77Skettenis     ps_stopped,
965b725ae77Skettenis     /* abnormal (but unsurprising) ways of stopping */
966b725ae77Skettenis     ps_lostwatch,
967b725ae77Skettenis     ps_branchthrough0, ps_undef, ps_caughtswi, ps_prefetch,
968b725ae77Skettenis     ps_abort, ps_addrexcept, ps_caughtirq, ps_caughtfiq,
969b725ae77Skettenis     ps_error,
970b725ae77Skettenis     /* only as a return value from Call() */
971b725ae77Skettenis     ps_callfailed, ps_callreturned,
972b725ae77Skettenis     /* internal inconsistencies */
973b725ae77Skettenis     ps_broken,                  /* target has "broken" */
974b725ae77Skettenis     ps_unknownbreak,
975b725ae77Skettenis     ps_unknown
976b725ae77Skettenis } Dbg_ProgramState;
977b725ae77Skettenis 
978b725ae77Skettenis int Dbg_IsCallLink(Dbg_MCState *state, ARMaddress pc);
979b725ae77Skettenis 
980b725ae77Skettenis typedef struct {
981b725ae77Skettenis     Dbg_FPRegVal fpres;
982b725ae77Skettenis     ARMword intres;
983b725ae77Skettenis } Dbg_CallResults;
984b725ae77Skettenis 
985b725ae77Skettenis Dbg_CallResults *Dbg_GetCallResults(Dbg_MCState *state);
986b725ae77Skettenis 
987b725ae77Skettenis #define Dbg_S_STATEMENTS 0
988b725ae77Skettenis #define Dbg_S_INSTRUCTIONS 1
989b725ae77Skettenis #define Dbg_S_STEPINTOPROCS 2
990b725ae77Skettenis 
991b725ae77Skettenis Dbg_Error Dbg_Step(Dbg_MCState *state, int32 stepcount, int stepby, Dbg_ProgramState *status);
992b725ae77Skettenis /*  <stepby> is a combination of the Dbg_S_... values above */
993b725ae77Skettenis 
994b725ae77Skettenis Dbg_Error Dbg_StepOut(Dbg_MCState *state, Dbg_ProgramState *status);
995b725ae77Skettenis 
996b725ae77Skettenis bool Dbg_CanGo(Dbg_MCState *state);
997b725ae77Skettenis 
998b725ae77Skettenis bool Dbg_IsExecuting(Dbg_MCState *state);
999b725ae77Skettenis 
1000b725ae77Skettenis Dbg_Error Dbg_Go(Dbg_MCState *state, Dbg_ProgramState *status);
1001b725ae77Skettenis 
1002b725ae77Skettenis Dbg_Error Dbg_Stop(Dbg_MCState *state);
1003b725ae77Skettenis /* Asynchronous Stop request, for call from SIGINT handler.  On return to the
1004b725ae77Skettenis    caller, the call of Dbg_Go, Dbg_Step or Dbg_Call which started execution
1005b725ae77Skettenis    should return ps_interrupted.
1006b725ae77Skettenis  */
1007b725ae77Skettenis 
1008b725ae77Skettenis typedef void Dbg_ExecuteProc(Dbg_MCState *state, Dbg_ProgramState status);
1009b725ae77Skettenis Dbg_Error Dbg_OnExecute(Dbg_MCState *, Dbg_ExecuteProc *);
1010b725ae77Skettenis /* Register function to be called back whenever execution stops.
1011b725ae77Skettenis  * (To allow multiple toolbox clients to coexist).
1012b725ae77Skettenis  */
1013b725ae77Skettenis 
1014b725ae77Skettenis Dbg_Error Dbg_SetReturn(Dbg_MCState *state,
1015b725ae77Skettenis                 const Dbg_Environment *context, const Dbg_Value *value);
1016b725ae77Skettenis /* Prepare continuation by returning <value> from the function activation
1017b725ae77Skettenis    described by <context>.  (Dbg_Go() or Dbg_Step() actually perform the
1018b725ae77Skettenis    continuation).
1019b725ae77Skettenis  */
1020b725ae77Skettenis 
1021b725ae77Skettenis Dbg_Error Dbg_SetExecution(Dbg_MCState *state, Dbg_Environment *context);
1022b725ae77Skettenis /* Set the pc in a high-level fashion */
1023b725ae77Skettenis 
1024b725ae77Skettenis Dbg_Error Dbg_ProgramStateToChars(Dbg_MCState *state, Dbg_ProgramState event, Dbg_BufDesc *buf);
1025b725ae77Skettenis /* This is guaranteed to give a completely accurate description of <event> if
1026b725ae77Skettenis    this was the value returned by the most recent call of Dbg_Go, Dbg_Step,
1027b725ae77Skettenis    or Dbg_Call.
1028b725ae77Skettenis  */
1029b725ae77Skettenis 
1030b725ae77Skettenis /*--------------------------------------------------------------------------*/
1031b725ae77Skettenis 
1032b725ae77Skettenis Dbg_Error Dbg_CurrentEnvironment(Dbg_MCState *state, Dbg_Environment *context);
1033b725ae77Skettenis 
1034b725ae77Skettenis Dbg_Error Dbg_PrevFrame(Dbg_MCState *state, Dbg_Environment *context);
1035b725ae77Skettenis /* towards the base of the stack */
1036b725ae77Skettenis 
1037b725ae77Skettenis Dbg_Error Dbg_NextFrame(Dbg_MCState *state, Dbg_Environment *context);
1038b725ae77Skettenis /* away from the base of the stack */
1039b725ae77Skettenis 
1040b725ae77Skettenis typedef struct Dbg_AnyPos {
1041b725ae77Skettenis     enum { pos_source, pos_ll, pos_none } postype;
1042b725ae77Skettenis     ARMaddress pc;
1043b725ae77Skettenis     union {
1044b725ae77Skettenis         Dbg_ProcPos source;
1045b725ae77Skettenis         Dbg_LLPos ll;
1046b725ae77Skettenis         ARMaddress none;
1047b725ae77Skettenis     } pos;
1048b725ae77Skettenis } Dbg_AnyPos;
1049b725ae77Skettenis 
1050b725ae77Skettenis Dbg_Error Dbg_EnvironmentToPos(Dbg_MCState *state, const Dbg_Environment *context, Dbg_AnyPos *pos);
1051b725ae77Skettenis /* <pos> is set to a Dbg_ProcPos if these is one corresponding to <context>
1052b725ae77Skettenis    else a Dbg_LLPos if there is one.
1053b725ae77Skettenis  */
1054b725ae77Skettenis 
1055b725ae77Skettenis /*--------------------------------------------------------------------------*/
1056b725ae77Skettenis 
1057b725ae77Skettenis /* Source file management.
1058b725ae77Skettenis    Pretty vestigial.  Handles source path (per loaded image),
1059b725ae77Skettenis    and translates from line-number (as given in debugger tables) to character
1060b725ae77Skettenis    position (as required to access files)
1061b725ae77Skettenis  */
1062b725ae77Skettenis 
1063b725ae77Skettenis Dbg_Error Dbg_ClearPaths(Dbg_MCState *state, Dbg_SymTable *st);
1064b725ae77Skettenis Dbg_Error Dbg_AddPath(Dbg_MCState *state, Dbg_SymTable *st, const char *path);
1065b725ae77Skettenis Dbg_Error Dbg_DeletePath(Dbg_MCState *state, Dbg_SymTable *st, const char *path);
1066b725ae77Skettenis 
1067b725ae77Skettenis typedef enum {
1068b725ae77Skettenis   Dbg_PathsCleared,
1069b725ae77Skettenis   Dbg_PathAdded,
1070b725ae77Skettenis   Dbg_PathDeleted
1071b725ae77Skettenis } Dbg_PathAlteration;
1072b725ae77Skettenis 
1073b725ae77Skettenis typedef void Dbg_PathAlteredProc(
1074b725ae77Skettenis     Dbg_MCState *state, Dbg_SymTable *st, char const *path,
1075b725ae77Skettenis     Dbg_PathAlteration sort);
1076b725ae77Skettenis 
1077b725ae77Skettenis Dbg_Error Dbg_OnPathAlteration(Dbg_MCState *state, Dbg_PathAlteredProc *p);
1078b725ae77Skettenis /* Register function to be called back whenever one of the source path
1079b725ae77Skettenis  * modification functions above is called. (To allow multiple toolbox
1080b725ae77Skettenis  * clients to coexist).
1081b725ae77Skettenis  */
1082b725ae77Skettenis 
1083b725ae77Skettenis typedef struct Dbg_FileRec Dbg_FileRec;
1084b725ae77Skettenis typedef struct {
1085b725ae77Skettenis   unsigned32 linecount;
1086b725ae77Skettenis   Dbg_FileRec *handle;
1087b725ae77Skettenis   char *fullname;
1088b725ae77Skettenis } Dbg_FileDetails;
1089b725ae77Skettenis 
1090b725ae77Skettenis Dbg_Error Dbg_GetFileDetails(
1091b725ae77Skettenis     Dbg_MCState *state, const Dbg_File *fname, Dbg_FileDetails *res);
1092b725ae77Skettenis Dbg_Error Dbg_FinishedWithFile(Dbg_MCState *state, Dbg_FileRec *handle);
1093b725ae77Skettenis 
1094b725ae77Skettenis Dbg_Error Dbg_GetFileDetails_fr(
1095b725ae77Skettenis     Dbg_MCState *state, Dbg_FileRec *handle, Dbg_FileDetails *res);
1096b725ae77Skettenis /* Refresh details about the file associated with <handle> (in particular,
1097b725ae77Skettenis  * its linecount).
1098b725ae77Skettenis  */
1099b725ae77Skettenis 
1100b725ae77Skettenis Dbg_Error Dbg_FileLineLength(
1101b725ae77Skettenis     Dbg_MCState *state, Dbg_FileRec *handle, int32 lineno, int32 *len);
1102b725ae77Skettenis /* Return to <len> the length of line <lineno> of the file associated with
1103b725ae77Skettenis  * <handle> (without necessarily reading from the file).
1104b725ae77Skettenis  */
1105b725ae77Skettenis 
1106b725ae77Skettenis Dbg_Error Dbg_GetFileLine_fr(
1107b725ae77Skettenis     Dbg_MCState *state, Dbg_FileRec *handle, int32 lineno, Dbg_BufDesc *buf);
1108b725ae77Skettenis /* Return to <buf> the contents of line <lineno> of the file associated with
1109b725ae77Skettenis  * <handle> (including its terminating newline).
1110b725ae77Skettenis  */
1111b725ae77Skettenis 
1112b725ae77Skettenis Dbg_Error Dbg_StartFileAccess(Dbg_MCState *state, Dbg_FileRec *handle);
1113b725ae77Skettenis Dbg_Error Dbg_EndFileAccess(Dbg_MCState *state, Dbg_FileRec *handle);
1114b725ae77Skettenis /* These two calls bracket a sequence of calls to GetFileLine. Between the
1115b725ae77Skettenis  * calls, the toolbox is permitted to retain state allowing more rapid
1116b725ae77Skettenis  * access to text on the file associated with <handle>.
1117b725ae77Skettenis  */
1118b725ae77Skettenis 
1119b725ae77Skettenis Dbg_Error Dbg_ControlSourceFileAccess(
1120b725ae77Skettenis     Dbg_MCState *state, uint32 cachesize, bool closefiles);
1121b725ae77Skettenis /* Control details of how the toolbox manages source files.
1122b725ae77Skettenis  *   If <cachesize> is non-zero, the text from the most recently accessed
1123b725ae77Skettenis  *     source files (of total size not to exceed <cachesize>) is saved in
1124b725ae77Skettenis  *     store on first access to the file; subsequent access to the text of
1125b725ae77Skettenis  *     the file uses this copy.
1126b725ae77Skettenis  *   If <closefiles> is true, no stream is left attached to uncached source
1127b725ae77Skettenis  *     files after Dbg_EndFileAccess has been closed. Otherwise, the toolbox
1128b725ae77Skettenis  *     may retain such streams, in order to improve access.
1129b725ae77Skettenis  */
1130b725ae77Skettenis 
1131b725ae77Skettenis /*--------------------------------------------------------------------------*/
1132b725ae77Skettenis 
1133b725ae77Skettenis /* disassembly */
1134b725ae77Skettenis 
1135b725ae77Skettenis /*
1136b725ae77Skettenis  ? More exact control is wanted here, but that requires a more complicated
1137b725ae77Skettenis  ? disass callback interface.
1138b725ae77Skettenis  */
1139b725ae77Skettenis 
1140b725ae77Skettenis typedef const char *Dbg_SWI_Decode(Dbg_MCState *state, ARMword swino);
1141b725ae77Skettenis 
1142b725ae77Skettenis Dbg_Error Dbg_InstructionAt(Dbg_MCState *state, ARMaddress addr,
1143b725ae77Skettenis                     int isize, ARMhword *inst, Dbg_SymTable *st,
1144b725ae77Skettenis                     Dbg_SWI_Decode *swi_name, Dbg_BufDesc *buf, int *length);
1145b725ae77Skettenis /* <isize> describes the form of disassembly wanted: 2 for 16-bit, 4 for 32-bit,
1146b725ae77Skettenis  * 0 for 16- or 32-bit depending whether addr addresses 16- or 32-bit code.
1147b725ae77Skettenis  * <inst> is a pointer to a pair of halfwords *in target byte order*
1148b725ae77Skettenis  * Possibly only the first halfword will be consumed: the number of bytes used
1149b725ae77Skettenis  * is returned via <length>.
1150b725ae77Skettenis  */
1151b725ae77Skettenis 
1152b725ae77Skettenis /*--------------------------------------------------------------------------*/
1153b725ae77Skettenis 
1154b725ae77Skettenis int Dbg_RDIOpen(Dbg_MCState *state, unsigned type);
1155b725ae77Skettenis int Dbg_RDIInfo(Dbg_MCState *state, unsigned type, ARMword *arg1, ARMword *arg2);
1156b725ae77Skettenis 
1157b725ae77Skettenis /*--------------------------------------------------------------------------*/
1158b725ae77Skettenis 
1159b725ae77Skettenis typedef enum {
1160b725ae77Skettenis     Dbg_Point_Toolbox,
1161b725ae77Skettenis     Dbg_Point_RDI_Unknown,
1162b725ae77Skettenis     Dbg_Point_RDI_SW,
1163b725ae77Skettenis     Dbg_Point_RDI_HW
1164b725ae77Skettenis } Dbg_PointType;
1165b725ae77Skettenis 
1166b725ae77Skettenis /* breakpoint management
1167b725ae77Skettenis    Associated with a breakpoint there may be any of
1168b725ae77Skettenis      a count
1169b725ae77Skettenis      an expression
1170b725ae77Skettenis      a function
1171b725ae77Skettenis    the breakpoint is activated if
1172b725ae77Skettenis         the expression evaluates to a non-zero value (or fails to evaluate).
1173b725ae77Skettenis      && decrementing the count reaches zero (the count is then reset to its
1174b725ae77Skettenis         initial value).
1175b725ae77Skettenis      && the function, called with the breakpoint address as argument, returns
1176b725ae77Skettenis         a non-zero value.
1177b725ae77Skettenis ?  (The order here may be open to debate.  Note that the first two are in
1178b725ae77Skettenis     the opposite order in armsd, but I think this order more rational)
1179b725ae77Skettenis  */
1180b725ae77Skettenis 
1181b725ae77Skettenis typedef enum Dbg_BreakPosType {
1182b725ae77Skettenis     bt_procpos,
1183b725ae77Skettenis     bt_procexit,
1184b725ae77Skettenis     bt_address
1185b725ae77Skettenis } Dbg_BreakPosType;
1186b725ae77Skettenis 
1187b725ae77Skettenis typedef union {
1188b725ae77Skettenis       Dbg_ProcPos procpos;
1189b725ae77Skettenis       Dbg_ProcDesc procexit;
1190b725ae77Skettenis       ARMaddress address;
1191b725ae77Skettenis } Dbg_BreakPosPos;
1192b725ae77Skettenis 
1193b725ae77Skettenis typedef struct Dbg_BreakPos {
1194b725ae77Skettenis     Dbg_BreakPosType sort;
1195b725ae77Skettenis     Dbg_BreakPosPos loc;
1196b725ae77Skettenis } Dbg_BreakPos;
1197b725ae77Skettenis 
1198b725ae77Skettenis typedef int Dbg_BPProc(Dbg_MCState *state, void *BPArg, Dbg_BreakPos *where);
1199b725ae77Skettenis 
1200b725ae77Skettenis typedef struct Dbg_BreakStatus {
1201b725ae77Skettenis     int index;
1202b725ae77Skettenis     int initcount, countnow;
1203b725ae77Skettenis     Dbg_BreakPos where;
1204b725ae77Skettenis     char *expr;
1205b725ae77Skettenis     Dbg_BPProc *p; void *p_arg;
1206b725ae77Skettenis     int incomplete;
1207b725ae77Skettenis     Dbg_PointType type;
1208b725ae77Skettenis     ARMword hwresource;
1209b725ae77Skettenis } Dbg_BreakStatus;
1210b725ae77Skettenis 
1211b725ae77Skettenis Dbg_Error Dbg_StringToBreakPos(
1212b725ae77Skettenis     Dbg_MCState *state, Dbg_Environment *env, char const *str, size_t len,
1213b725ae77Skettenis     Dbg_BreakPos *bpos, char *b);
1214b725ae77Skettenis 
1215b725ae77Skettenis Dbg_Error Dbg_SetBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where,
1216b725ae77Skettenis                     int count,
1217b725ae77Skettenis                     const char *expr,
1218b725ae77Skettenis                     Dbg_BPProc *p, void *arg);
1219b725ae77Skettenis Dbg_Error Dbg_SetBreakPoint16(Dbg_MCState *state, Dbg_BreakPos *where,
1220b725ae77Skettenis                     int count,
1221b725ae77Skettenis                     const char *expr,
1222b725ae77Skettenis                     Dbg_BPProc *p, void *arg);
1223b725ae77Skettenis Dbg_Error Dbg_SetBreakPointNaturalSize(Dbg_MCState *state, Dbg_BreakPos *where,
1224b725ae77Skettenis                     int count,
1225b725ae77Skettenis                     const char *expr,
1226b725ae77Skettenis                     Dbg_BPProc *p, void *arg);
1227b725ae77Skettenis /* Setting a breakpoint at the same address as a previous breakpoint
1228b725ae77Skettenis    completely removes the previous one.
1229b725ae77Skettenis  */
1230b725ae77Skettenis 
1231b725ae77Skettenis Dbg_Error Dbg_DeleteBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where);
1232b725ae77Skettenis 
1233b725ae77Skettenis Dbg_Error Dbg_SuspendBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where);
1234b725ae77Skettenis /* Temporarily remove the break point (until Reinstated) but leave intact
1235b725ae77Skettenis    its associated expr, the value its count has reached, etc.
1236b725ae77Skettenis ?  The debugger toolbox itself wants this, but I'm not sure what use a client
1237b725ae77Skettenis    could have for it.  Ditto Reinstate...
1238b725ae77Skettenis  */
1239b725ae77Skettenis 
1240b725ae77Skettenis Dbg_Error Dbg_ReinstateBreakPoint(Dbg_MCState *state, Dbg_BreakPos *where);
1241b725ae77Skettenis /* Undo the effect of Dbg_SuspendBreakPoint
1242b725ae77Skettenis  */
1243b725ae77Skettenis 
1244b725ae77Skettenis Dbg_Error Dbg_DeleteAllBreakPoints(Dbg_MCState *state);
1245b725ae77Skettenis 
1246b725ae77Skettenis Dbg_Error Dbg_SuspendAllBreakPoints(Dbg_MCState *state);
1247b725ae77Skettenis 
1248b725ae77Skettenis Dbg_Error Dbg_ReinstateAllBreakPoints(Dbg_MCState *state);
1249b725ae77Skettenis 
1250b725ae77Skettenis typedef Dbg_Error Dbg_BPEnumProc(Dbg_MCState *state, Dbg_BreakStatus *status, void *arg);
1251b725ae77Skettenis 
1252b725ae77Skettenis Dbg_Error Dbg_EnumerateBreakPoints(Dbg_MCState *state, Dbg_BPEnumProc *p, void *arg);
1253b725ae77Skettenis 
1254b725ae77Skettenis Dbg_Error Dbg_BreakPointStatus(Dbg_MCState *state,
1255b725ae77Skettenis                        const Dbg_BreakPos *where, Dbg_BreakStatus *status);
1256b725ae77Skettenis 
1257b725ae77Skettenis typedef void Dbg_BreakAlteredProc(Dbg_MCState *state, ARMaddress addr, bool set);
1258b725ae77Skettenis Dbg_Error Dbg_OnBreak(Dbg_MCState *state, Dbg_BreakAlteredProc *p);
1259b725ae77Skettenis /* Register function to be called back whenever a breakpoint is set or
1260b725ae77Skettenis  * cleared. (To allow multiple toolbox clients to coexist).
1261b725ae77Skettenis  */
1262b725ae77Skettenis 
1263b725ae77Skettenis bool Dbg_StoppedAtBreakPoint(Dbg_MCState *state, const Dbg_BreakPos *where);
1264b725ae77Skettenis /* Called after execution which resulted in ps_atbreak, to find out whether
1265b725ae77Skettenis    the specified breakpoint was hit (could be >1, eg. exit break and another
1266b725ae77Skettenis    high-level breakpoint at the same position).
1267b725ae77Skettenis    Returns NO if specified breakpoint not found, or execution didn't stop
1268b725ae77Skettenis    with ps_atbreak status.
1269b725ae77Skettenis  */
1270b725ae77Skettenis 
1271b725ae77Skettenis /*--------------------------------------------------------------------------*/
1272b725ae77Skettenis 
1273b725ae77Skettenis typedef struct {
1274b725ae77Skettenis   Dbg_Value val;
1275b725ae77Skettenis   char *name;
1276b725ae77Skettenis } Dbg_WatchPos;
1277b725ae77Skettenis 
1278b725ae77Skettenis typedef int Dbg_WPProc(Dbg_MCState *state, void *WPArg, Dbg_WatchPos *where);
1279b725ae77Skettenis 
1280b725ae77Skettenis typedef struct Dbg_WPStatus {
1281b725ae77Skettenis     int index;
1282b725ae77Skettenis     int initcount, countnow;
1283b725ae77Skettenis     Dbg_WatchPos what, target;
1284b725ae77Skettenis     char *expr;
1285b725ae77Skettenis     Dbg_WPProc *p; void *p_arg;
1286b725ae77Skettenis     Dbg_PointType type;
1287b725ae77Skettenis     ARMword hwresource;
1288b725ae77Skettenis     int skip;
1289b725ae77Skettenis } Dbg_WPStatus;
1290b725ae77Skettenis 
1291b725ae77Skettenis Dbg_Error Dbg_SetWatchPoint(
1292b725ae77Skettenis     Dbg_MCState *state, Dbg_Environment *context, char const *watchee,
1293b725ae77Skettenis     char const *target,
1294b725ae77Skettenis     int count,
1295b725ae77Skettenis     char const *expr,
1296b725ae77Skettenis     Dbg_WPProc *p, void *arg);
1297b725ae77Skettenis 
1298b725ae77Skettenis /* Cause a watchpoint event if the value of <watchee> changes to the value of
1299b725ae77Skettenis    <target> (or changes at all if <target> is NULL).  <watchee> should
1300b725ae77Skettenis    evaluate either to an L-value (when the size of the object being watched is
1301b725ae77Skettenis    determined by its type) or to an integer constant (when the word with this
1302b725ae77Skettenis    address is watched).
1303b725ae77Skettenis  */
1304b725ae77Skettenis 
1305b725ae77Skettenis Dbg_Error Dbg_DeleteWatchPoint(Dbg_MCState *state, Dbg_Environment *context, char const *watchee);
1306b725ae77Skettenis 
1307b725ae77Skettenis 
1308b725ae77Skettenis Dbg_Error Dbg_SetWatchPoint_V(
1309b725ae77Skettenis     Dbg_MCState *state,
1310b725ae77Skettenis     char const *name, Dbg_Value const *val, char const *tname, Dbg_Value const *tval,
1311b725ae77Skettenis     int count,
1312b725ae77Skettenis     char const *expr,
1313b725ae77Skettenis     Dbg_WPProc *p, void *arg);
1314b725ae77Skettenis 
1315b725ae77Skettenis Dbg_Error Dbg_DeleteWatchPoint_V(Dbg_MCState *state, Dbg_Value const *val);
1316b725ae77Skettenis 
1317b725ae77Skettenis 
1318b725ae77Skettenis Dbg_Error Dbg_DeleteAllWatchPoints(Dbg_MCState *state);
1319b725ae77Skettenis 
1320b725ae77Skettenis typedef Dbg_Error Dbg_WPEnumProc(Dbg_MCState *state, Dbg_WPStatus const *watchee, void *arg);
1321b725ae77Skettenis 
1322b725ae77Skettenis Dbg_Error Dbg_EnumerateWatchPoints(Dbg_MCState *state, Dbg_WPEnumProc *p, void *arg);
1323b725ae77Skettenis 
1324b725ae77Skettenis Dbg_Error Dbg_WatchPointStatus(Dbg_MCState *state,
1325b725ae77Skettenis                        Dbg_WatchPos const *where, Dbg_WPStatus *status);
1326b725ae77Skettenis 
1327b725ae77Skettenis typedef void Dbg_WPRemovedProc(void *arg, Dbg_WPStatus const *wp);
1328b725ae77Skettenis Dbg_Error Dbg_RegisterWPRemovalProc(Dbg_MCState *state, Dbg_WPRemovedProc *p, void *arg);
1329b725ae77Skettenis /* When a watchpoint goes out of scope it is removed by the toolbox, and the
1330b725ae77Skettenis    function registered here gets called back to adjust its view
1331b725ae77Skettenis  */
1332b725ae77Skettenis 
1333b725ae77Skettenis typedef void Dbg_WatchAlteredProc(Dbg_MCState *state, Dbg_Value const *where, bool set);
1334b725ae77Skettenis Dbg_Error Dbg_OnWatch(Dbg_MCState *state, Dbg_WatchAlteredProc *p);
1335b725ae77Skettenis /* Register function to be called back whenever a watchpoint is set or
1336b725ae77Skettenis  * cleared. (To allow multiple toolbox clients to coexist).
1337b725ae77Skettenis  */
1338b725ae77Skettenis 
1339b725ae77Skettenis /*--------------------------------------------------------------------------*/
1340b725ae77Skettenis 
1341b725ae77Skettenis Dbg_Error Dbg_ProfileLoad(Dbg_MCState *state);
1342b725ae77Skettenis 
1343b725ae77Skettenis Dbg_Error Dbg_ProfileStart(Dbg_MCState *state, ARMword interval);
1344b725ae77Skettenis Dbg_Error Dbg_ProfileStop(Dbg_MCState *state);
1345b725ae77Skettenis 
1346b725ae77Skettenis Dbg_Error Dbg_ProfileClear(Dbg_MCState *state);
1347b725ae77Skettenis 
1348b725ae77Skettenis Dbg_Error Dbg_WriteProfile(Dbg_MCState *state, char const *filename,
1349b725ae77Skettenis                            char const *toolid, char const *arg);
1350b725ae77Skettenis 
1351b725ae77Skettenis /*--------------------------------------------------------------------------*/
1352b725ae77Skettenis 
1353b725ae77Skettenis Dbg_Error Dbg_ConnectChannel_ToHost(Dbg_MCState *state, RDICCProc_ToHost *p, void *arg);
1354b725ae77Skettenis Dbg_Error Dbg_ConnectChannel_FromHost(Dbg_MCState *state, RDICCProc_FromHost *p, void *arg);
1355b725ae77Skettenis 
1356b725ae77Skettenis /*--------------------------------------------------------------------------*/
1357b725ae77Skettenis 
1358b725ae77Skettenis /* Configuration data management */
1359b725ae77Skettenis 
1360b725ae77Skettenis Dbg_Error Dbg_LoadConfigData(Dbg_MCState *state, char const *filename);
1361b725ae77Skettenis 
1362b725ae77Skettenis Dbg_Error Dbg_SelectConfig(
1363b725ae77Skettenis     Dbg_MCState *state,
1364b725ae77Skettenis     RDI_ConfigAspect aspect, char const *name, RDI_ConfigMatchType matchtype,
1365b725ae77Skettenis     unsigned versionreq, unsigned *versionp);
1366b725ae77Skettenis 
1367b725ae77Skettenis Dbg_Error Dbg_ParseConfigVersion(
1368b725ae77Skettenis     char const *s, RDI_ConfigMatchType *matchp, unsigned *versionp);
1369b725ae77Skettenis 
1370b725ae77Skettenis typedef Dbg_Error Dbg_ConfigEnumProc(Dbg_MCState *state, RDI_ConfigDesc const *desc, void *arg);
1371b725ae77Skettenis 
1372b725ae77Skettenis Dbg_Error Dbg_EnumerateConfigs(Dbg_MCState *state, Dbg_ConfigEnumProc *p, void *arg);
1373b725ae77Skettenis 
1374b725ae77Skettenis /*--------------------------------------------------------------------------*/
1375b725ae77Skettenis 
1376b725ae77Skettenis /* Angel OS support */
1377b725ae77Skettenis 
1378b725ae77Skettenis Dbg_Error Dbg_CreateTask(Dbg_MCState **statep, Dbg_MCState *parent, bool inherit);
1379b725ae77Skettenis /* This is called when a task is to be debugged which has not been debugged
1380b725ae77Skettenis    before - ie. there is no existing Dbg_MCState for this task. It
1381b725ae77Skettenis    initialises a new Dbg_MCState and returns a pointer to it.
1382b725ae77Skettenis    <parent> is any valid previously-created MCCState. If <inherit> is TRUE,
1383b725ae77Skettenis    the new MCState inherits certain features from it (eg. symbols).
1384b725ae77Skettenis    Otherwise, only features which are the same across all tasks are inherited,
1385b725ae77Skettenis    (eg. global breakpoints).
1386b725ae77Skettenis  */
1387b725ae77Skettenis 
1388b725ae77Skettenis Dbg_Error Dbg_DeleteTask(Dbg_MCState *state);
1389b725ae77Skettenis /* This is called when a task dies, and frees up everything which relates to that
1390b725ae77Skettenis    task which is controlled by armdbg.
1391b725ae77Skettenis  */
1392b725ae77Skettenis 
1393b725ae77Skettenis Dbg_Error Dbg_DetachTask(Dbg_MCState *state);
1394b725ae77Skettenis 
1395b725ae77Skettenis Dbg_Error Dbg_AttachTask(Dbg_MCState *state);
1396b725ae77Skettenis /* These are called to request a switch of the current task.  First
1397b725ae77Skettenis    Dbg_DetachTask should be called with the state of the old task.
1398b725ae77Skettenis    Dbg_DetachTask will ensure that any cached state held by armdbg for
1399b725ae77Skettenis    the old task is immediately written out to the target.
1400b725ae77Skettenis 
1401b725ae77Skettenis    After Dbg_DetachTask is called and before Dbg_AttachTask is called
1402b725ae77Skettenis    the OS channel manager should tell the target that any future
1403b725ae77Skettenis    requests from the debugger will be fore the new task.
1404b725ae77Skettenis 
1405b725ae77Skettenis    If the new task does not have an armdbg state structure
1406b725ae77Skettenis    already, then Dbg_CreateTask should be called to create one (see
1407b725ae77Skettenis    above).  Then Dbg_AttachTask is called to tell armdbg to treat the
1408b725ae77Skettenis    new armdbg state as the current task.
1409b725ae77Skettenis  */
1410b725ae77Skettenis 
1411b725ae77Skettenis typedef Dbg_Error Dbg_TaskSwitchProc(void *arg, Dbg_MCState *newstate);
1412b725ae77Skettenis 
1413b725ae77Skettenis Dbg_Error Dbg_OnTaskSwitch(Dbg_MCState *state, Dbg_TaskSwitchProc *fn, void *arg);
1414b725ae77Skettenis /* The front end may register a callback which gets called by armdbg whenever
1415b725ae77Skettenis    Dbg_AttachTask is called.  This callback tells the front end the new current
1416b725ae77Skettenis    Dbg_MCState it should use to call armdbg.
1417b725ae77Skettenis    [Note that this is only useful if there is one front end shared between all
1418b725ae77Skettenis     tasks rather than one front end per task]
1419b725ae77Skettenis    The value of <arg> passed to Dbg_OnTaskSwitch is passed to <fn>
1420b725ae77Skettenis    when it is called.
1421b725ae77Skettenis  */
1422b725ae77Skettenis 
1423b725ae77Skettenis typedef Dbg_Error Dbg_RestartProc(
1424b725ae77Skettenis     void *arg, Dbg_MCState *curstate, Dbg_MCState **newstate);
1425b725ae77Skettenis 
1426b725ae77Skettenis Dbg_Error Dbg_OnRestart(Dbg_MCState *state, Dbg_RestartProc *fn, void *arg);
1427b725ae77Skettenis /* This is used by the OS channels layer to register a callback which
1428b725ae77Skettenis    will be made by the debugger toolbox early in the process of resuming
1429b725ae77Skettenis    execution.
1430b725ae77Skettenis 
1431b725ae77Skettenis    This callback must determine which task will be resumed when the target
1432b725ae77Skettenis    restarts execution.  If this is not already the current task then it must
1433b725ae77Skettenis    call Dbg_DetachTask and Dbg_AttachTask as decribed above to switch to the
1434b725ae77Skettenis    task about to be resumed and return the state for the new task in
1435b725ae77Skettenis    <newstate>.
1436b725ae77Skettenis 
1437b725ae77Skettenis    This will ensure that armdbg updates the correct task on execution as well
1438b725ae77Skettenis    as ensuring that stepping over a breakpointed instruction on restarting
1439b725ae77Skettenis    happens correctly.
1440b725ae77Skettenis 
1441b725ae77Skettenis    The value of <arg> passed to Dbg_OnRestart is passed to <fn>
1442b725ae77Skettenis    when it is called.
1443b725ae77Skettenis  */
1444b725ae77Skettenis 
1445b725ae77Skettenis 
1446b725ae77Skettenis #ifdef __cplusplus
1447b725ae77Skettenis }
1448b725ae77Skettenis #endif
1449b725ae77Skettenis 
1450b725ae77Skettenis #endif
1451b725ae77Skettenis 
1452b725ae77Skettenis /* End of armdbg.h */
1453