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