forked from Imagelibrary/binutils-gdb
Compare commits
1 Commits
gdb-8.1.1-
...
binutils-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63c56504a0 |
@@ -1,9 +0,0 @@
|
||||
The files in this directory are shared with other debuggers and
|
||||
debug interfaces that use Advanced Micro Devices' UDI (universal debug
|
||||
interface) protocol. The protocol provides a common interface among
|
||||
debuggers, logic analyzers, emulators, and embedded systems that use
|
||||
AMD 29000 family processors.
|
||||
|
||||
Do not change these files without coordinating with Advanced Micro
|
||||
Devices, Embedded Processor Division, 5204 E. Ben White Blvd, Austin, TX 78741.
|
||||
Maybe postmaster@cayman.amd.com can direct you to the current maintainers.
|
||||
@@ -1,607 +0,0 @@
|
||||
/*
|
||||
|
||||
Interface from UDI calls in 32-bit mode to go32 in 16-bit mode.
|
||||
Communication is done through a single interrupt vector, which passes
|
||||
data through two linear buffers.
|
||||
|
||||
Call:
|
||||
AH = 0xfe
|
||||
AL = UDI function number
|
||||
ECX = IN length
|
||||
ESI = pointer to IN buffer
|
||||
EDI = pointer to OUT buffer
|
||||
|
||||
Return:
|
||||
EAX = return value of UDI function
|
||||
|
||||
Vector:
|
||||
0x21
|
||||
|
||||
*/
|
||||
#ifdef __GO32__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "udiproc.h"
|
||||
#include "udisoc.h"
|
||||
|
||||
char dfe_errmsg[500];
|
||||
|
||||
static char in_buffer[4096];
|
||||
static char out_buffer[4096];
|
||||
static char *in_ptr;
|
||||
static char *out_ptr;
|
||||
|
||||
#define IN_INIT() in_ptr = in_buffer
|
||||
#define IN_VAL(t,v) *((t *)in_ptr)++ = v
|
||||
#define IN_DATA(ptr, cnt) memcpy(in_ptr, ptr, cnt), in_ptr += cnt
|
||||
|
||||
#define OUT_INIT() out_ptr = out_buffer
|
||||
#define OUT_VAL(t) (*((t *)out_ptr)++)
|
||||
#define OUT_DATA(ptr, cnt) memcpy(ptr, out_ptr, cnt), out_ptr += cnt
|
||||
|
||||
static int DO_CALL(int function)
|
||||
{
|
||||
asm("pushl %esi");
|
||||
asm("pushl %edi");
|
||||
asm("movb %0, %%al" : : "g" (function));
|
||||
asm("movl _in_ptr, %ecx");
|
||||
asm("movl $_in_buffer, %esi");
|
||||
asm("subl %esi, %ecx");
|
||||
asm("movl $_out_buffer, %edi");
|
||||
asm("movb $0xfe, %ah");
|
||||
asm("int $0x21");
|
||||
asm("popl %edi");
|
||||
asm("popl %esi");
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#ifdef TEST_UDI
|
||||
int main()
|
||||
{
|
||||
int r;
|
||||
long p2;
|
||||
short p1;
|
||||
IN_INIT();
|
||||
IN_VAL(long, 11111111);
|
||||
IN_VAL(short, 2222);
|
||||
IN_DATA("Hello, world\n", 17);
|
||||
|
||||
r = DO_CALL(42);
|
||||
|
||||
OUT_INIT();
|
||||
p1 = OUT_VAL(short);
|
||||
p2 = OUT_VAL(long);
|
||||
printf("main: p1=%d p2=%d rv=%d\n", p1, p2, r);
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
unsupported(char *s)
|
||||
{
|
||||
printf("unsupported UDI host call %s\n", s);
|
||||
abort();
|
||||
}
|
||||
|
||||
UDIError UDIConnect (
|
||||
char *Configuration, /* In */
|
||||
UDISessionId *Session /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
out_buffer[0] = 0; /* DJ - test */
|
||||
IN_INIT();
|
||||
IN_DATA(Configuration, strlen(Configuration)+1);
|
||||
|
||||
r = DO_CALL(UDIConnect_c);
|
||||
|
||||
OUT_INIT();
|
||||
*Session = OUT_VAL(UDISessionId);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIDisconnect (
|
||||
UDISessionId Session, /* In */
|
||||
UDIBool Terminate /* In */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
IN_VAL(UDISessionId, Session);
|
||||
IN_VAL(UDIBool, Terminate);
|
||||
|
||||
return DO_CALL(UDIDisconnect_c);
|
||||
}
|
||||
|
||||
UDIError UDISetCurrentConnection (
|
||||
UDISessionId Session /* In */
|
||||
)
|
||||
{
|
||||
IN_INIT();
|
||||
IN_VAL(UDISessionId, Session);
|
||||
|
||||
return DO_CALL(UDISetCurrentConnection_c);
|
||||
}
|
||||
|
||||
UDIError UDICapabilities (
|
||||
UDIUInt32 *TIPId, /* Out */
|
||||
UDIUInt32 *TargetId, /* Out */
|
||||
UDIUInt32 DFEId, /* In */
|
||||
UDIUInt32 DFE, /* In */
|
||||
UDIUInt32 *TIP, /* Out */
|
||||
UDIUInt32 *DFEIPCId, /* Out */
|
||||
UDIUInt32 *TIPIPCId, /* Out */
|
||||
char *TIPString /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
IN_VAL(UDIUInt32, DFEId);
|
||||
IN_VAL(UDIUInt32, DFE);
|
||||
r = DO_CALL(UDICapabilities_c);
|
||||
OUT_INIT();
|
||||
*TIPId = OUT_VAL(UDIUInt32);
|
||||
*TargetId = OUT_VAL(UDIUInt32);
|
||||
*TIP = OUT_VAL(UDIUInt32);
|
||||
*DFEIPCId = OUT_VAL(UDIUInt32);
|
||||
*TIPIPCId = OUT_VAL(UDIUInt32);
|
||||
strcpy(TIPString, out_ptr);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIEnumerateTIPs (
|
||||
UDIInt (*UDIETCallback) /* In */
|
||||
( char *Configuration ) /* In to callback() */
|
||||
)
|
||||
{
|
||||
UDIETCallback("montip.exe");
|
||||
}
|
||||
|
||||
UDIError UDIGetErrorMsg (
|
||||
UDIError ErrorCode, /* In */
|
||||
UDISizeT MsgSize, /* In */
|
||||
char *Msg, /* Out */
|
||||
UDISizeT *CountDone /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
if (MsgSize > 4000)
|
||||
MsgSize = 4000;
|
||||
IN_INIT();
|
||||
IN_VAL(UDIError, ErrorCode);
|
||||
IN_VAL(UDISizeT, MsgSize);
|
||||
|
||||
r = DO_CALL(UDIGetErrorMsg_c);
|
||||
|
||||
OUT_INIT();
|
||||
*CountDone = OUT_VAL(UDISizeT);
|
||||
OUT_DATA(Msg, *CountDone);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIGetTargetConfig (
|
||||
UDIMemoryRange KnownMemory[], /* Out */
|
||||
UDIInt *NumberOfRanges, /* In/Out */
|
||||
UDIUInt32 ChipVersions[], /* Out */
|
||||
UDIInt *NumberOfChips /* In/Out */
|
||||
)
|
||||
{
|
||||
int r, i;
|
||||
int nr = *NumberOfRanges;
|
||||
int nc = *NumberOfChips;
|
||||
IN_INIT();
|
||||
IN_VAL(UDIInt, *NumberOfRanges);
|
||||
IN_VAL(UDIInt, *NumberOfChips);
|
||||
r = DO_CALL(UDIGetTargetConfig_c);
|
||||
if (r == UDIErrorIncomplete)
|
||||
return r;
|
||||
OUT_INIT();
|
||||
*NumberOfRanges = OUT_VAL(UDIInt);
|
||||
*NumberOfChips = OUT_VAL(UDIInt);
|
||||
for (i=0; i<nr; i++)
|
||||
{
|
||||
KnownMemory[i].Space = OUT_VAL(short);
|
||||
KnownMemory[i].Offset = OUT_VAL(CPUOffset);
|
||||
KnownMemory[i].Size = OUT_VAL(CPUSizeT);
|
||||
}
|
||||
for (i=0; i<nc; i++)
|
||||
{
|
||||
ChipVersions[i] = OUT_VAL(UDIUInt32);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDICreateProcess (
|
||||
UDIPId *PId /* Out */
|
||||
)
|
||||
{
|
||||
int r = DO_CALL(UDICreateProcess_c);
|
||||
|
||||
OUT_INIT();
|
||||
*PId = OUT_VAL(UDIPId);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDISetCurrentProcess (
|
||||
UDIPId PId /* In */
|
||||
)
|
||||
{
|
||||
IN_INIT();
|
||||
IN_VAL(UDIPId, PId);
|
||||
|
||||
return DO_CALL(UDISetCurrentProcess_c);
|
||||
}
|
||||
|
||||
UDIError UDIDestroyProcess (
|
||||
UDIPId PId /* In */
|
||||
)
|
||||
{
|
||||
IN_INIT();
|
||||
IN_VAL(UDIPId, PId);
|
||||
|
||||
return DO_CALL(UDIDestroyProcess_c);
|
||||
}
|
||||
|
||||
UDIError UDIInitializeProcess (
|
||||
UDIMemoryRange ProcessMemory[], /* In */
|
||||
UDIInt NumberOfRanges, /* In */
|
||||
UDIResource EntryPoint, /* In */
|
||||
CPUSizeT StackSizes[], /* In */
|
||||
UDIInt NumberOfStacks, /* In */
|
||||
char *ArgString /* In */
|
||||
)
|
||||
{
|
||||
int i, r;
|
||||
IN_INIT();
|
||||
IN_VAL(UDIInt, NumberOfRanges);
|
||||
for (i=0; i<NumberOfRanges; i++)
|
||||
{
|
||||
IN_VAL(short, ProcessMemory[i].Space);
|
||||
IN_VAL(CPUOffset, ProcessMemory[i].Offset);
|
||||
IN_VAL(CPUSizeT, ProcessMemory[i].Size);
|
||||
}
|
||||
IN_VAL(short, EntryPoint.Space);
|
||||
IN_VAL(CPUOffset, EntryPoint.Offset);
|
||||
IN_VAL(UDIInt, NumberOfStacks);
|
||||
for (i=0; i<NumberOfStacks; i++)
|
||||
IN_VAL(CPUSizeT, StackSizes[i]);
|
||||
IN_DATA(ArgString, strlen(ArgString)+1);
|
||||
|
||||
return DO_CALL(UDIInitializeProcess_c);
|
||||
}
|
||||
|
||||
UDIError UDIRead (
|
||||
UDIResource From, /* In */
|
||||
UDIHostMemPtr To, /* Out */
|
||||
UDICount Count, /* In */
|
||||
UDISizeT Size, /* In */
|
||||
UDICount *CountDone, /* Out */
|
||||
UDIBool HostEndian /* In */
|
||||
)
|
||||
{
|
||||
int cleft = Count, cthis, dthis;
|
||||
int cdone = 0, r, bsize=2048/Size;
|
||||
|
||||
while (cleft)
|
||||
{
|
||||
cthis = (cleft<bsize) ? cleft : bsize;
|
||||
IN_INIT();
|
||||
IN_VAL(short, From.Space);
|
||||
IN_VAL(CPUOffset, From.Offset);
|
||||
IN_VAL(UDICount, cthis);
|
||||
IN_VAL(UDISizeT, Size);
|
||||
IN_VAL(UDIBool, HostEndian);
|
||||
|
||||
r = DO_CALL(UDIRead_c);
|
||||
|
||||
OUT_INIT();
|
||||
dthis = OUT_VAL(UDICount);
|
||||
OUT_DATA(To, dthis*Size);
|
||||
cdone += dthis;
|
||||
To += dthis*Size;
|
||||
|
||||
if (r != UDINoError)
|
||||
{
|
||||
*CountDone = cdone;
|
||||
return r;
|
||||
}
|
||||
cleft -= cthis;
|
||||
}
|
||||
*CountDone = cdone;
|
||||
return UDINoError;
|
||||
}
|
||||
|
||||
UDIError UDIWrite (
|
||||
UDIHostMemPtr From, /* In */
|
||||
UDIResource To, /* In */
|
||||
UDICount Count, /* In */
|
||||
UDISizeT Size, /* In */
|
||||
UDICount *CountDone, /* Out */
|
||||
UDIBool HostEndian /* In */
|
||||
)
|
||||
{
|
||||
int cleft = Count, cthis, dthis;
|
||||
int cdone = 0, r, bsize=2048/Size;
|
||||
|
||||
while (cleft)
|
||||
{
|
||||
cthis = (cleft<bsize) ? cleft : bsize;
|
||||
IN_INIT();
|
||||
IN_VAL(short, To.Space);
|
||||
IN_VAL(CPUOffset, To.Offset);
|
||||
IN_VAL(UDICount, cthis);
|
||||
IN_VAL(UDISizeT, Size);
|
||||
IN_VAL(UDIBool, HostEndian);
|
||||
IN_DATA(From, cthis*Size);
|
||||
From += cthis*Size;
|
||||
|
||||
r = DO_CALL(UDIWrite_c);
|
||||
|
||||
OUT_INIT();
|
||||
cdone += OUT_VAL(UDICount);
|
||||
|
||||
if (r != UDINoError)
|
||||
{
|
||||
*CountDone = cdone;
|
||||
return r;
|
||||
}
|
||||
cleft -= cthis;
|
||||
}
|
||||
*CountDone = cdone;
|
||||
return UDINoError;
|
||||
}
|
||||
|
||||
UDIError UDICopy (
|
||||
UDIResource From, /* In */
|
||||
UDIResource To, /* In */
|
||||
UDICount Count, /* In */
|
||||
UDISizeT Size, /* In */
|
||||
UDICount *CountDone, /* Out */
|
||||
UDIBool Direction /* In */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
IN_VAL(short, From.Space);
|
||||
IN_VAL(CPUOffset, From.Offset);
|
||||
IN_VAL(short, To.Space);
|
||||
IN_VAL(CPUOffset, To.Offset);
|
||||
IN_VAL(UDICount, Count);
|
||||
IN_VAL(UDISizeT, Size);
|
||||
IN_VAL(UDIBool, Direction);
|
||||
|
||||
r = DO_CALL(UDICopy_c);
|
||||
|
||||
OUT_INIT();
|
||||
*CountDone = OUT_VAL(UDICount);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIExecute (
|
||||
void
|
||||
)
|
||||
{
|
||||
return DO_CALL(UDIExecute_c);
|
||||
}
|
||||
|
||||
UDIError UDIStep (
|
||||
UDIUInt32 Steps, /* In */
|
||||
UDIStepType StepType, /* In */
|
||||
UDIRange Range /* In */
|
||||
)
|
||||
{
|
||||
IN_INIT();
|
||||
IN_VAL(UDIUInt32, Steps);
|
||||
IN_VAL(UDIStepType, StepType);
|
||||
IN_VAL(UDIRange, Range);
|
||||
|
||||
return DO_CALL(UDIStep_c);
|
||||
}
|
||||
|
||||
UDIVoid UDIStop (
|
||||
void
|
||||
)
|
||||
{
|
||||
DO_CALL(UDIStop_c);
|
||||
}
|
||||
|
||||
UDIError UDIWait (
|
||||
UDIInt32 MaxTime, /* In */
|
||||
UDIPId *PId, /* Out */
|
||||
UDIUInt32 *StopReason /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
IN_VAL(UDIInt32, MaxTime);
|
||||
r = DO_CALL(UDIWait_c);
|
||||
OUT_INIT();
|
||||
*PId = OUT_VAL(UDIPId);
|
||||
*StopReason = OUT_VAL(UDIUInt32);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDISetBreakpoint (
|
||||
UDIResource Addr, /* In */
|
||||
UDIInt32 PassCount, /* In */
|
||||
UDIBreakType Type, /* In */
|
||||
UDIBreakId *BreakId /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
IN_VAL(short, Addr.Space);
|
||||
IN_VAL(CPUOffset, Addr.Offset);
|
||||
IN_VAL(UDIInt32, PassCount);
|
||||
IN_VAL(UDIBreakType, Type);
|
||||
|
||||
r = DO_CALL(UDISetBreakpoint_c);
|
||||
|
||||
OUT_INIT();
|
||||
*BreakId = OUT_VAL(UDIBreakId);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIQueryBreakpoint (
|
||||
UDIBreakId BreakId, /* In */
|
||||
UDIResource *Addr, /* Out */
|
||||
UDIInt32 *PassCount, /* Out */
|
||||
UDIBreakType *Type, /* Out */
|
||||
UDIInt32 *CurrentCount /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
IN_VAL(UDIBreakId, BreakId);
|
||||
|
||||
r = DO_CALL(UDIQueryBreakpoint_c);
|
||||
|
||||
OUT_INIT();
|
||||
Addr->Space = OUT_VAL(short);
|
||||
Addr->Offset = OUT_VAL(CPUOffset);
|
||||
*PassCount = OUT_VAL(UDIInt32);
|
||||
*Type = OUT_VAL(UDIBreakType);
|
||||
*CurrentCount = OUT_VAL(UDIInt32);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIClearBreakpoint (
|
||||
UDIBreakId BreakId /* In */
|
||||
)
|
||||
{
|
||||
IN_INIT();
|
||||
IN_VAL(UDIBreakId, BreakId);
|
||||
|
||||
return DO_CALL(UDIClearBreakpoint_c);
|
||||
}
|
||||
|
||||
UDIError UDIGetStdout (
|
||||
UDIHostMemPtr Buf, /* Out */
|
||||
UDISizeT BufSize, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
if (BufSize > 4000)
|
||||
BufSize = 4000;
|
||||
IN_VAL(UDISizeT,BufSize);
|
||||
r = DO_CALL(UDIGetStdout_c);
|
||||
OUT_INIT();
|
||||
*CountDone = OUT_VAL(UDISizeT);
|
||||
if (*CountDone <= BufSize)
|
||||
OUT_DATA(Buf, *CountDone);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIGetStderr (
|
||||
UDIHostMemPtr Buf, /* Out */
|
||||
UDISizeT BufSize, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
if (BufSize > 4000)
|
||||
BufSize = 4000;
|
||||
IN_VAL(UDISizeT,BufSize);
|
||||
r = DO_CALL(UDIGetStderr_c);
|
||||
OUT_INIT();
|
||||
*CountDone = OUT_VAL(UDISizeT);
|
||||
OUT_DATA(Buf, *CountDone);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIPutStdin (
|
||||
UDIHostMemPtr Buf, /* In */
|
||||
UDISizeT Count, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
if (Count > 4000)
|
||||
Count = 4000;
|
||||
IN_VAL(UDISizeT,Count);
|
||||
IN_DATA(Buf, Count);
|
||||
r = DO_CALL(UDIPutStdin_c);
|
||||
OUT_INIT();
|
||||
*CountDone = OUT_VAL(UDISizeT);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIStdinMode (
|
||||
UDIMode *Mode /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
r = DO_CALL(UDIStdinMode_c);
|
||||
OUT_INIT();
|
||||
*Mode = OUT_VAL(UDIMode);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIPutTrans (
|
||||
UDIHostMemPtr Buf, /* In */
|
||||
UDISizeT Count, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
if (Count > 4000)
|
||||
Count = 4000;
|
||||
IN_VAL(UDISizeT,Count);
|
||||
IN_DATA(Buf, Count);
|
||||
r = DO_CALL(UDIPutTrans_c);
|
||||
OUT_INIT();
|
||||
*CountDone = OUT_VAL(UDISizeT);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDIGetTrans (
|
||||
UDIHostMemPtr Buf, /* Out */
|
||||
UDISizeT BufSize, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
if (BufSize > 4000)
|
||||
BufSize = 4000;
|
||||
IN_VAL(UDISizeT,BufSize);
|
||||
r = DO_CALL(UDIGetTrans_c);
|
||||
OUT_INIT();
|
||||
*CountDone = OUT_VAL(UDISizeT);
|
||||
OUT_DATA(Buf, *CountDone);
|
||||
return r;
|
||||
}
|
||||
|
||||
UDIError UDITransMode (
|
||||
UDIMode *Mode /* Out */
|
||||
)
|
||||
{
|
||||
int r;
|
||||
IN_INIT();
|
||||
r = DO_CALL(UDITransMode_c);
|
||||
OUT_INIT();
|
||||
*Mode = OUT_VAL(UDIMode);
|
||||
return r;
|
||||
}
|
||||
|
||||
#define DFEIPCIdCompany 0x0001 /* Company ID AMD */
|
||||
#define DFEIPCIdProduct 0x1 /* Product ID 0 */
|
||||
#define DFEIPCIdVersion 0x125 /* 1.2.5 */
|
||||
|
||||
unsigned UDIGetDFEIPCId ()
|
||||
{
|
||||
return((((UDIUInt32)DFEIPCIdCompany) << 16) |(DFEIPCIdProduct << 12) | DFEIPCIdVersion);
|
||||
}
|
||||
|
||||
#endif /* __GO32__ */
|
||||
@@ -1,48 +0,0 @@
|
||||
/* This file contains the DFE and TIP IDs to be used by AMD products for
|
||||
the UDICapabilities call.
|
||||
|
||||
Copyright 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Company Codes -- AMD assigns these */
|
||||
#define UDICompanyCode_AMD 1
|
||||
|
||||
/* Build a UDIID given a CompanyProdCode and 3 version pieces */
|
||||
#define UDIID(CompanyProdCode, v1,v2,v3) ((((CompanyProdCode) & 0xfffff)<<12)+\
|
||||
(((v1)&0xf)<<8) + (((v2)&0xf)<<4) + ((v3)&0xf))
|
||||
|
||||
|
||||
/* Extract a CompanyProdCode or a Version from a UDIID */
|
||||
#define UDIID_CompanyProdCode(id) (((id)>>12) & 0xfffff)
|
||||
#define UDIID_Version(id) ((id)&0xfff)
|
||||
|
||||
|
||||
#define UDIAMDProduct(ProdCode) ((UDICompanyCode_AMD<<4) + (ProdCode&0xf))
|
||||
|
||||
/* AMD DFE Product Codes */
|
||||
#define UDIProductCode_Mondfe UDIAMDProduct(0)
|
||||
#define UDIProductCode_XRAY UDIAMDProduct(1)
|
||||
#define UDIProductCode_TIPTester UDIAMDProduct(2)
|
||||
|
||||
/* AMD TIP Product Codes (need not be distinct from DFE Product Codes) */
|
||||
#define UDIProductCode_Montip UDIAMDProduct(0)
|
||||
#define UDIProductCode_Isstip UDIAMDProduct(1)
|
||||
|
||||
|
||||
#define UDILatestVersion 0x120 /* UDI 1.2.0, can be used in DFE and TIP desired UDI params */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,44 +0,0 @@
|
||||
/* This file just picks the correct udiphxxx.h depending on the host.
|
||||
The two hosts that are now defined are UNIX and MSDOS.
|
||||
|
||||
Copyright 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/*
|
||||
* For the moment, we will default to BSD_IPC; this might change if/when
|
||||
* another type of IPC (Mach? SysV?) is implemented.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
|
||||
/* We don't seem to have a copy of udiphdos.h. Furthermore, all the
|
||||
things in udiphunix.h are pretty much generic 32-bit machine defines
|
||||
which don't have anything to do with IPC. */
|
||||
|
||||
#ifdef DOS_IPC
|
||||
#include "udiphdos.h"
|
||||
#else
|
||||
/*#ifdef BSD_IPC */
|
||||
#include "udiphunix.h"
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include "udiphunix.h"
|
||||
|
||||
#endif
|
||||
@@ -1,81 +0,0 @@
|
||||
/* Originally called "udiphsun.h", however it was not very
|
||||
Sun-specific; now it is used for generic-unix-with-bsd-ipc.
|
||||
|
||||
Copyright 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This file is to be used to reconfigure the UDI Procedural interface
|
||||
for a given host. This file should be placed so that it will be
|
||||
included from udiproc.h. Everything in here may need to be changed
|
||||
when you change either the host CPU or its compiler. Nothing in
|
||||
here should change to support different targets. There are multiple
|
||||
versions of this file, one for each of the different host/compiler
|
||||
combinations in use.
|
||||
*/
|
||||
|
||||
#define UDIStruct struct /* _packed not needed on unix */
|
||||
/* First, we need some types */
|
||||
/* Types with at least the specified number of bits */
|
||||
typedef double UDIReal64; /* 64-bit real value */
|
||||
typedef float UDIReal32; /* 32-bit real value */
|
||||
|
||||
typedef unsigned long UDIUInt32; /* unsigned integers */
|
||||
typedef unsigned short UDIUInt16;
|
||||
typedef unsigned char UDIUInt8;
|
||||
|
||||
typedef long UDIInt32; /* 32-bit integer */
|
||||
typedef short UDIInt16; /* 16-bit integer */
|
||||
typedef char UDIInt8; /* unreliable signedness */
|
||||
|
||||
/* To aid in supporting environments where the DFE and TIP use
|
||||
different compilers or hosts (like DOS 386 on one side, 286 on the
|
||||
other, or different Unix machines connected by sockets), we define
|
||||
two abstract types - UDIInt and UDISizeT.
|
||||
UDIInt should be defined to be int except for host/compiler combinations
|
||||
that are intended to talk to existing UDI components that have a different
|
||||
sized int. Similarly for UDISizeT.
|
||||
*/
|
||||
typedef int UDIInt;
|
||||
typedef unsigned int UDIUInt;
|
||||
|
||||
typedef unsigned int UDISizeT;
|
||||
|
||||
/* Now two void types. The first is for function return types,
|
||||
the other for pointers to no particular type. Since these types
|
||||
are used solely for documentational clarity, if your host/compiler
|
||||
doesn't support either one, replace them with int and char *
|
||||
respectively.
|
||||
*/
|
||||
typedef void UDIVoid; /* void type */
|
||||
typedef void * UDIVoidPtr; /* void pointer type */
|
||||
typedef void * UDIHostMemPtr; /* Arbitrary memory pointer */
|
||||
|
||||
/* Now we want a type optimized for boolean values. Normally this
|
||||
would be int, but on some machines (Z80s, 8051s, etc) it might
|
||||
be better to map it onto a char
|
||||
*/
|
||||
typedef int UDIBool;
|
||||
|
||||
/* Now indicate whether your compiler support full ANSI style
|
||||
prototypes. If so, use #if 1. If not use #if 0.
|
||||
*/
|
||||
#if 0
|
||||
#define UDIParams(x) x
|
||||
#else
|
||||
#define UDIParams(x) ()
|
||||
#endif
|
||||
@@ -1,308 +0,0 @@
|
||||
/* local type decs. and macro defs.
|
||||
|
||||
Copyright 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "udiphcfg.h" /* Get host specific configuration */
|
||||
#include "udiptcfg.h" /* Get target specific configuration */
|
||||
|
||||
/* Here are all of the CPU Families for which UDI is currently defined */
|
||||
#define Am29K 1 /* AMD's Am290xx and Am292xx parts */
|
||||
|
||||
typedef UDIInt UDIError;
|
||||
typedef UDIInt UDISessionId;
|
||||
typedef UDIInt UDIPId;
|
||||
typedef UDIInt UDIStepType;
|
||||
typedef UDIInt UDIBreakType;
|
||||
typedef UDIUInt UDIBreakId;
|
||||
typedef UDIUInt UDIMode;
|
||||
|
||||
typedef UDIStruct
|
||||
{
|
||||
CPUSpace Space;
|
||||
CPUOffset Offset;
|
||||
} UDIResource;
|
||||
|
||||
typedef UDIStruct
|
||||
{
|
||||
CPUOffset Low;
|
||||
CPUOffset High;
|
||||
} UDIRange;
|
||||
|
||||
typedef UDIStruct
|
||||
{
|
||||
CPUSpace Space;
|
||||
CPUOffset Offset;
|
||||
CPUSizeT Size;
|
||||
} UDIMemoryRange;
|
||||
|
||||
/* Values for UDIStepType parameters */
|
||||
#define UDIStepNatural 0x0000
|
||||
#define UDIStepOverTraps 0x0001
|
||||
#define UDIStepOverCalls 0x0002
|
||||
#define UDIStepInRange 0x0004
|
||||
#define UDIStepNatural 0x0000
|
||||
|
||||
/* Values for UDIBreakType parameters */
|
||||
#define UDIBreakFlagExecute 0x0001
|
||||
#define UDIBreakFlagRead 0x0002
|
||||
#define UDIBreakFlagWrite 0x0004
|
||||
#define UDIBreakFlagFetch 0x0008
|
||||
|
||||
/* Special values for UDIWait MaxTime parameter */
|
||||
#define UDIWaitForever (UDIInt32) -1 /* Infinite time delay */
|
||||
|
||||
/* Special values for PId */
|
||||
#define UDIProcessProcessor -1 /* Raw Hardware, if possible */
|
||||
|
||||
/* Values for UDIWait StopReason */
|
||||
#define UDIGrossState 0xff
|
||||
#define UDITrapped 0 /* Fine state - which trap */
|
||||
#define UDINotExecuting 1
|
||||
#define UDIRunning 2
|
||||
#define UDIStopped 3
|
||||
#define UDIWarned 4
|
||||
#define UDIStepped 5
|
||||
#define UDIWaiting 6
|
||||
#define UDIHalted 7
|
||||
#define UDIStdoutReady 8 /* fine state - size */
|
||||
#define UDIStderrReady 9 /* fine state - size */
|
||||
#define UDIStdinNeeded 10 /* fine state - size */
|
||||
#define UDIStdinModeX 11 /* fine state - mode */
|
||||
#define UDIBreak 12 /* Fine state - Breakpoint Id */
|
||||
#define UDIExited 13 /* Fine state - exit code */
|
||||
|
||||
/* Enumerate the return values from the callback function
|
||||
for UDIEnumerateTIPs.
|
||||
*/
|
||||
#define UDITerminateEnumeration 0
|
||||
#define UDIContinueEnumeration 1
|
||||
|
||||
/* Enumerate values for Terminate parameter to UDIDisconnect */
|
||||
#define UDITerminateSession 1
|
||||
#define UDIContinueSession 0
|
||||
|
||||
/* Error codes */
|
||||
#define UDINoError 0 /* No error occured */
|
||||
#define UDIErrorNoSuchConfiguration 1
|
||||
#define UDIErrorCantHappen 2
|
||||
#define UDIErrorCantConnect 3
|
||||
#define UDIErrorNoSuchConnection 4
|
||||
#define UDIErrorNoConnection 5
|
||||
#define UDIErrorCantOpenConfigFile 6
|
||||
#define UDIErrorCantStartTIP 7
|
||||
#define UDIErrorConnectionUnavailable 8
|
||||
#define UDIErrorTryAnotherTIP 9
|
||||
#define UDIErrorExecutableNotTIP 10
|
||||
#define UDIErrorInvalidTIPOption 11
|
||||
#define UDIErrorCantDisconnect 12
|
||||
#define UDIErrorUnknownError 13
|
||||
#define UDIErrorCantCreateProcess 14
|
||||
#define UDIErrorNoSuchProcess 15
|
||||
#define UDIErrorUnknownResourceSpace 16
|
||||
#define UDIErrorInvalidResource 17
|
||||
#define UDIErrorUnsupportedStepType 18
|
||||
#define UDIErrorCantSetBreakpoint 19
|
||||
#define UDIErrorTooManyBreakpoints 20
|
||||
#define UDIErrorInvalidBreakId 21
|
||||
#define UDIErrorNoMoreBreakIds 22
|
||||
#define UDIErrorUnsupportedService 23
|
||||
#define UDIErrorTryAgain 24
|
||||
#define UDIErrorIPCLimitation 25
|
||||
#define UDIErrorIncomplete 26
|
||||
#define UDIErrorAborted 27
|
||||
#define UDIErrorTransDone 28
|
||||
#define UDIErrorCantAccept 29
|
||||
#define UDIErrorTransInputNeeded 30
|
||||
#define UDIErrorTransModeX 31
|
||||
#define UDIErrorInvalidSize 32
|
||||
#define UDIErrorBadConfigFileEntry 33
|
||||
#define UDIErrorIPCInternal 34
|
||||
/* TBD */
|
||||
|
||||
/****************************************************************** PROCEDURES
|
||||
*/
|
||||
|
||||
UDIError UDIConnect UDIParams((
|
||||
char *Configuration, /* In */
|
||||
UDISessionId *Session /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIDisconnect UDIParams((
|
||||
UDISessionId Session, /* In */
|
||||
UDIBool Terminate /* In */
|
||||
));
|
||||
|
||||
UDIError UDISetCurrentConnection UDIParams((
|
||||
UDISessionId Session /* In */
|
||||
));
|
||||
|
||||
UDIError UDICapabilities UDIParams((
|
||||
UDIUInt32 *TIPId, /* Out */
|
||||
UDIUInt32 *TargetId, /* Out */
|
||||
UDIUInt32 DFEId, /* In */
|
||||
UDIUInt32 DFE, /* In */
|
||||
UDIUInt32 *TIP, /* Out */
|
||||
UDIUInt32 *DFEIPCId, /* Out */
|
||||
UDIUInt32 *TIPIPCId, /* Out */
|
||||
char *TIPString /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIEnumerateTIPs UDIParams((
|
||||
UDIInt (*UDIETCallback) /* In */
|
||||
UDIParams(( char *Configuration )) /* In to callback() */
|
||||
));
|
||||
|
||||
UDIError UDIGetErrorMsg UDIParams((
|
||||
UDIError ErrorCode, /* In */
|
||||
UDISizeT MsgSize, /* In */
|
||||
char *Msg, /* Out */
|
||||
UDISizeT *CountDone /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIGetTargetConfig UDIParams((
|
||||
UDIMemoryRange KnownMemory[], /* Out */
|
||||
UDIInt *NumberOfRanges, /* In/Out */
|
||||
UDIUInt32 ChipVersions[], /* Out */
|
||||
UDIInt *NumberOfChips /* In/Out */
|
||||
));
|
||||
|
||||
UDIError UDICreateProcess UDIParams((
|
||||
UDIPId *PId /* Out */
|
||||
));
|
||||
|
||||
UDIError UDISetCurrentProcess UDIParams((
|
||||
UDIPId PId /* In */
|
||||
));
|
||||
|
||||
UDIError UDIDestroyProcess UDIParams((
|
||||
UDIPId PId /* In */
|
||||
));
|
||||
|
||||
UDIError UDIInitializeProcess UDIParams((
|
||||
UDIMemoryRange ProcessMemory[], /* In */
|
||||
UDIInt NumberOfRanges, /* In */
|
||||
UDIResource EntryPoint, /* In */
|
||||
CPUSizeT StackSizes[], /* In */
|
||||
UDIInt NumberOfStacks, /* In */
|
||||
char *ArgString /* In */
|
||||
));
|
||||
|
||||
UDIError UDIRead UDIParams((
|
||||
UDIResource From, /* In */
|
||||
UDIHostMemPtr To, /* Out */
|
||||
UDICount Count, /* In */
|
||||
UDISizeT Size, /* In */
|
||||
UDICount *CountDone, /* Out */
|
||||
UDIBool HostEndian /* In */
|
||||
));
|
||||
|
||||
UDIError UDIWrite UDIParams((
|
||||
UDIHostMemPtr From, /* In */
|
||||
UDIResource To, /* In */
|
||||
UDICount Count, /* In */
|
||||
UDISizeT Size, /* In */
|
||||
UDICount *CountDone, /* Out */
|
||||
UDIBool HostEndian /* In */
|
||||
));
|
||||
|
||||
UDIError UDICopy UDIParams((
|
||||
UDIResource From, /* In */
|
||||
UDIResource To, /* In */
|
||||
UDICount Count, /* In */
|
||||
UDISizeT Size, /* In */
|
||||
UDICount *CountDone, /* Out */
|
||||
UDIBool Direction /* In */
|
||||
));
|
||||
|
||||
UDIError UDIExecute UDIParams((
|
||||
void
|
||||
));
|
||||
|
||||
UDIError UDIStep UDIParams((
|
||||
UDIUInt32 Steps, /* In */
|
||||
UDIStepType StepType, /* In */
|
||||
UDIRange Range /* In */
|
||||
));
|
||||
|
||||
UDIVoid UDIStop UDIParams((
|
||||
void
|
||||
));
|
||||
|
||||
UDIError UDIWait UDIParams((
|
||||
UDIInt32 MaxTime, /* In */
|
||||
UDIPId *PId, /* Out */
|
||||
UDIUInt32 *StopReason /* Out */
|
||||
));
|
||||
|
||||
UDIError UDISetBreakpoint UDIParams((
|
||||
UDIResource Addr, /* In */
|
||||
UDIInt32 PassCount, /* In */
|
||||
UDIBreakType Type, /* In */
|
||||
UDIBreakId *BreakId /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIQueryBreakpoint UDIParams((
|
||||
UDIBreakId BreakId, /* In */
|
||||
UDIResource *Addr, /* Out */
|
||||
UDIInt32 *PassCount, /* Out */
|
||||
UDIBreakType *Type, /* Out */
|
||||
UDIInt32 *CurrentCount /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIClearBreakpoint UDIParams((
|
||||
UDIBreakId BreakId /* In */
|
||||
));
|
||||
|
||||
UDIError UDIGetStdout UDIParams((
|
||||
UDIHostMemPtr Buf, /* Out */
|
||||
UDISizeT BufSize, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIGetStderr UDIParams((
|
||||
UDIHostMemPtr Buf, /* Out */
|
||||
UDISizeT BufSize, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIPutStdin UDIParams((
|
||||
UDIHostMemPtr Buf, /* In */
|
||||
UDISizeT Count, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIStdinMode UDIParams((
|
||||
UDIMode *Mode /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIPutTrans UDIParams((
|
||||
UDIHostMemPtr Buf, /* In */
|
||||
UDISizeT Count, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
));
|
||||
|
||||
UDIError UDIGetTrans UDIParams((
|
||||
UDIHostMemPtr Buf, /* Out */
|
||||
UDISizeT BufSize, /* In */
|
||||
UDISizeT *CountDone /* Out */
|
||||
));
|
||||
|
||||
UDIError UDITransMode UDIParams((
|
||||
UDIMode *Mode /* Out */
|
||||
));
|
||||
@@ -1,87 +0,0 @@
|
||||
/* This file is to be used to reconfigure the UDI Procedural interface
|
||||
for a given target.
|
||||
|
||||
Copyright 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This file should be placed so that it will be
|
||||
included from udiproc.h. Everything in here will probably need to
|
||||
be changed when you change the target processor. Nothing in here
|
||||
should need to change when you change hosts or compilers.
|
||||
*/
|
||||
|
||||
/* Select a target CPU Family */
|
||||
#define TargetCPUFamily Am29K
|
||||
|
||||
/* Enumerate the processor specific values for Space in a resource */
|
||||
#define UDI29KDRAMSpace 0
|
||||
#define UDI29KIOSpace 1
|
||||
#define UDI29KCPSpace0 2
|
||||
#define UDI29KCPSpace1 3
|
||||
#define UDI29KIROMSpace 4
|
||||
#define UDI29KIRAMSpace 5
|
||||
#define UDI29KLocalRegs 8
|
||||
#define UDI29KGlobalRegs 9
|
||||
#define UDI29KRealRegs 10
|
||||
#define UDI29KSpecialRegs 11
|
||||
#define UDI29KTLBRegs 12 /* Not Am29005 */
|
||||
#define UDI29KACCRegs 13 /* Am29050 only */
|
||||
#define UDI29KICacheSpace 14 /* Am2903x only */
|
||||
#define UDI29KAm29027Regs 15 /* When available */
|
||||
#define UDI29KPC 16
|
||||
#define UDI29KDCacheSpace 17 /* When available */
|
||||
|
||||
/* Enumerate the Co-processor registers */
|
||||
#define UDI29KCP_F 0
|
||||
#define UDI29KCP_Flag 8
|
||||
#define UDI29KCP_I 12
|
||||
#define UDI29KCP_ITmp 16
|
||||
#define UDI29KCP_R 20
|
||||
#define UDI29KCP_S 28
|
||||
#define UDI29KCP_RTmp 36
|
||||
#define UDI29KCP_STmp 44
|
||||
#define UDI29KCP_Stat 52
|
||||
#define UDI29KCP_Prec 56
|
||||
#define UDI29KCP_Reg0 60
|
||||
#define UDI29KCP_Reg1 68
|
||||
#define UDI29KCP_Reg2 76
|
||||
#define UDI29KCP_Reg3 84
|
||||
#define UDI29KCP_Reg4 92
|
||||
#define UDI29KCP_Reg5 100
|
||||
#define UDI29KCP_Reg6 108
|
||||
#define UDI29KCP_Reg7 116
|
||||
#define UDI29KCP_Mode 124
|
||||
|
||||
/* Enumerate the stacks in StackSizes array */
|
||||
#define UDI29KMemoryStack 0
|
||||
#define UDI29KRegisterStack 1
|
||||
|
||||
/* Enumerate the chips for ChipVersions array */
|
||||
#define UDI29K29KVersion 0
|
||||
#define UDI29K29027Version 1
|
||||
|
||||
/* Define special value for elements of ChipVersions array for
|
||||
* chips not present */
|
||||
#define UDI29KChipNotPresent -1
|
||||
|
||||
typedef UDIInt32 UDICount;
|
||||
typedef UDIUInt32 UDISize;
|
||||
|
||||
typedef UDIInt CPUSpace;
|
||||
typedef UDIUInt32 CPUOffset;
|
||||
typedef UDIUInt32 CPUSizeT;
|
||||
@@ -1,19 +0,0 @@
|
||||
/* Copyright 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "udipt29k.h"
|
||||
@@ -1,184 +0,0 @@
|
||||
/* This module defines constants used in the UDI IPC modules.
|
||||
|
||||
Copyright 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
static char udisoc_h[]="@(#)udisoc.h 2.6 Daniel Mann";
|
||||
static char udisoc_h_AMD[]="@(#)udisoc.h 2.4, AMD";
|
||||
|
||||
#define LOCAL static
|
||||
#define company_c 1 /* AMD Company id */
|
||||
#define product_c 1 /* socket IPC id */
|
||||
|
||||
/* Enumerate the UDI procedure services
|
||||
*/
|
||||
#define UDIConnect_c 0
|
||||
#define UDIDisconnect_c 1
|
||||
#define UDISetCurrentConnection_c 2
|
||||
#define UDICapabilities_c 3
|
||||
#define UDIEnumerateTIPs_c 4
|
||||
#define UDIGetErrorMsg_c 5
|
||||
#define UDIGetTargetConfig_c 6
|
||||
#define UDICreateProcess_c 7
|
||||
#define UDISetCurrentProcess_c 8
|
||||
#define UDIDestroyProcess_c 9
|
||||
#define UDIInitializeProcess_c 10
|
||||
#define UDIRead_c 11
|
||||
#define UDIWrite_c 12
|
||||
#define UDICopy_c 13
|
||||
#define UDIExecute_c 14
|
||||
#define UDIStep_c 15
|
||||
#define UDIStop_c 16
|
||||
#define UDIWait_c 17
|
||||
#define UDISetBreakpoint_c 18
|
||||
#define UDIQueryBreakpoint_c 19
|
||||
#define UDIClearBreakpoint_c 20
|
||||
#define UDIGetStdout_c 21
|
||||
#define UDIGetStderr_c 22
|
||||
#define UDIPutStdin_c 23
|
||||
#define UDIStdinMode_c 24
|
||||
#define UDIPutTrans_c 25
|
||||
#define UDIGetTrans_c 26
|
||||
#define UDITransMode_c 27
|
||||
#define UDITest_c 28
|
||||
#define UDIKill_c 29
|
||||
|
||||
#define udr_UDIInt8(udrs, obj) udr_work(udrs, obj, 1)
|
||||
#define udr_UDIInt16(udrs, obj) udr_work(udrs, obj, 2)
|
||||
#define udr_UDIInt32(udrs, obj) udr_work(udrs, obj, 4)
|
||||
#define udr_UDIInt(udrs, obj) udr_work(udrs, obj, 4)
|
||||
|
||||
#define udr_UDIUInt8(udrs, obj) udr_work(udrs, obj, 1)
|
||||
#define udr_UDIUInt16(udrs, obj) udr_work(udrs, obj, 2)
|
||||
#define udr_UDIUInt32(udrs, obj) udr_work(udrs, obj, 4)
|
||||
#define udr_UDIUInt(udrs, obj) udr_work(udrs, obj, 4)
|
||||
|
||||
#define udr_UDIBool(udrs, obj) udr_UDIInt32(udrs, obj)
|
||||
#define udr_UDICount(udrs, obj) udr_UDIInt32(udrs, obj)
|
||||
#define udr_UDISize(udrs, obj) udr_UDIUInt32(udrs, obj)
|
||||
#define udr_CPUSpace(udrs, obj) udr_UDIInt32(udrs, obj)
|
||||
#define udr_CPUOffset(udrs, obj) udr_UDIUInt32(udrs, obj)
|
||||
#define udr_CPUSizeT(udrs, obj) udr_UDIUInt32(udrs, obj)
|
||||
#define udr_UDIBreakId(udrs,obj) udr_UDIUInt(udrs, obj)
|
||||
#define udr_UDISizeT(udrs, obj) udr_UDIUInt(udrs, obj)
|
||||
#define udr_UDIMode(udrs, obj) udr_UDIUInt(udrs, obj)
|
||||
|
||||
#define udr_UDIHostMemPtr(udrs, obj) udr_UDIUInt32(udrs, obj)
|
||||
#define udr_UDIVoidPtr(udrs, obj) udr_UDIUInt32(udrs, obj)
|
||||
#define udr_UDIPId(udrs, obj) udr_UDIUInt(udrs, obj)
|
||||
#define udr_UDISessionId(udrs, obj) udr_UDIInt32(udrs, obj)
|
||||
#define udr_UDIError(udrs, obj) udr_UDIInt32(udrs, obj)
|
||||
#define udr_UDIStepType(udrs, obj) udr_UDIInt32(udrs, obj)
|
||||
#define udr_UDIBreakType(udrs, obj) udr_UDIInt32(udrs, obj)
|
||||
|
||||
|
||||
#define UDR_ENCODE 1
|
||||
#define UDR_DECODE 2
|
||||
|
||||
typedef struct UDR_str
|
||||
{
|
||||
int udr_op; /* UDR operation */
|
||||
int previous_op;
|
||||
int sd;
|
||||
int bufsize;
|
||||
char* buff;
|
||||
char* getbytes;
|
||||
char* putbytes;
|
||||
char* putend;
|
||||
int domain;
|
||||
char* soc_name;
|
||||
} UDR;
|
||||
|
||||
/******************************************* Declare UDR suport functions */
|
||||
int udr_create UDIParams((
|
||||
UDR* udrs,
|
||||
int sd,
|
||||
int size
|
||||
));
|
||||
|
||||
int udr_free UDIParams((
|
||||
UDR* udrs,
|
||||
));
|
||||
|
||||
int udr_signal UDIParams((
|
||||
UDR* udrs,
|
||||
));
|
||||
|
||||
int udr_sendnow UDIParams((
|
||||
UDR* udrs
|
||||
));
|
||||
|
||||
int udr_work UDIParams((
|
||||
UDR* udrs,
|
||||
void* object_p,
|
||||
int size
|
||||
));
|
||||
|
||||
int udr_UDIResource UDIParams((
|
||||
UDR* udrs,
|
||||
UDIResource* object_p
|
||||
));
|
||||
|
||||
int udr_UDIRange UDIParams((
|
||||
UDR* udrs,
|
||||
UDIRange* object_p
|
||||
));
|
||||
|
||||
int udr_UDIMemoryRange UDIParams((
|
||||
UDR* udrs,
|
||||
UDIMemoryRange* object_p
|
||||
));
|
||||
|
||||
int udr_UDIMemoryRange UDIParams((
|
||||
UDR* udrs,
|
||||
UDIMemoryRange* object_p
|
||||
));
|
||||
|
||||
int udr_int UDIParams((
|
||||
UDR* udrs,
|
||||
int* int_p
|
||||
));
|
||||
|
||||
int udr_bytes UDIParams((
|
||||
UDR* udrs,
|
||||
char* ptr,
|
||||
int len
|
||||
));
|
||||
|
||||
char* udr_inline UDIParams((
|
||||
UDR* udrs,
|
||||
int size
|
||||
));
|
||||
|
||||
char* udr_getpos UDIParams((
|
||||
UDR* udrs
|
||||
));
|
||||
int udr_setpos UDIParams((
|
||||
UDR* udrs,
|
||||
char* pos
|
||||
));
|
||||
|
||||
int udr_readnow UDIParams((
|
||||
UDR* udrs,
|
||||
int size
|
||||
));
|
||||
|
||||
int udr_align UDIParams((
|
||||
UDR* udrs,
|
||||
int size,
|
||||
));
|
||||
@@ -1,427 +0,0 @@
|
||||
/* This module supports sending and receiving data objects over a
|
||||
socket conection.
|
||||
|
||||
Copyright 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
static char udr_c[]="@(#)udr.c 2.8 Daniel Mann";
|
||||
static char udr_c_AMD[]="@(#)udr.c 2.3, AMD";
|
||||
/*
|
||||
* All data is serialised into a character stream,
|
||||
* and de-serialised back into the approproiate objects.
|
||||
********************************************************************** HISTORY
|
||||
*/
|
||||
/* This is all unneeded on DOS machines. */
|
||||
#ifndef __GO32__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* This used to say sys/fcntl.h, but the only systems I know of that
|
||||
require that are old (pre-4.3, at least) BSD systems, which we
|
||||
probably don't need to worry about. */
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include "udiproc.h"
|
||||
#include "udisoc.h"
|
||||
|
||||
extern int errno;
|
||||
extern char* malloc();
|
||||
|
||||
/* local type decs. and macro defs. not in a .h file ************* MACRO/TYPE
|
||||
*/
|
||||
|
||||
/* global dec/defs. which are not in a .h file ************* EXPORT DEC/DEFS
|
||||
*/
|
||||
int udr_errno; /* error occurs during UDR service */
|
||||
|
||||
/* local dec/defs. which are not in a .h file *************** LOCAL DEC/DEFS
|
||||
*/
|
||||
|
||||
/****************************************************************** UDR_CREATE
|
||||
* Build UDR structure for character stream processing.
|
||||
*/
|
||||
int udr_create(udrs, sd, size)
|
||||
UDR* udrs;
|
||||
int sd;
|
||||
int size;
|
||||
{
|
||||
udrs->sd = sd;
|
||||
if(!udrs->buff) udrs->buff = malloc(size);
|
||||
udrs->getbytes = udrs->buff; /* set the buffer to the start */
|
||||
udrs->putbytes = udrs->buff;
|
||||
udrs->putend = udrs->buff;
|
||||
udrs->udr_op = -1; /* don't know the direction */
|
||||
udrs->previous_op = -1; /* don't know the direction */
|
||||
udrs->bufsize = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************** UDR_FREE
|
||||
* Free USR structure and close socket.
|
||||
*/
|
||||
int udr_free(udrs)
|
||||
UDR* udrs;
|
||||
{
|
||||
close(udrs->sd);
|
||||
free(udrs->buff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************** UDR_SIGNAL
|
||||
* Send a signal to the process at the other end of the socket,
|
||||
* indicating that it should expect to recieve a new message shortly.
|
||||
*/
|
||||
int udr_signal(udrs)
|
||||
UDR* udrs;
|
||||
{
|
||||
if(send(udrs->sd, "I", 1, MSG_OOB) == -1)
|
||||
{ perror("ERROR, udr_signal(), send(...MSG_OOB)");
|
||||
udr_errno = UDIErrorIPCInternal;
|
||||
return -1; /* return error code */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************** UDR_SENDNOW
|
||||
* used to flush the current character stream buffer to
|
||||
* the associated socket. */
|
||||
int udr_sendnow(udrs)
|
||||
UDR* udrs;
|
||||
{
|
||||
int size = (UDIUInt32)(udrs->putend) - (UDIUInt32)(udrs->buff);
|
||||
if(udrs->previous_op == 0)
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return -1;
|
||||
}
|
||||
udrs->putbytes = udrs->buff;
|
||||
udrs->putend = udrs->buff;
|
||||
if (write(udrs->sd, udrs->buff, size) == -1)
|
||||
{ perror("ERROR, udr_sendnow(), write() call: ");
|
||||
udr_errno = UDIErrorIPCInternal;
|
||||
return -1; /* return error code */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************** UDR_WORK
|
||||
* Function to send or recieve data from the buffers supporting
|
||||
* socket communication. The buffer contains serialised objects
|
||||
* sent/recieved over a socket connection.
|
||||
*/
|
||||
int udr_work(udrs, object_p, size)
|
||||
UDR* udrs;
|
||||
void* object_p;
|
||||
int size;
|
||||
{
|
||||
int cnt, remain;
|
||||
|
||||
if(udrs->udr_op != udrs->previous_op)
|
||||
{ if(udrs->previous_op == 0)
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return -1;
|
||||
}
|
||||
udrs->previous_op= udrs->udr_op;
|
||||
udrs->putbytes = udrs->buff;
|
||||
udrs->getbytes = udrs->buff;
|
||||
}
|
||||
|
||||
if(udrs->udr_op == UDR_ENCODE)
|
||||
{ /* write data into character stream buffer */
|
||||
if( (UDIUInt32)(udrs->putbytes) + size >
|
||||
(UDIUInt32)(udrs->buff) + (UDIUInt32)(udrs->bufsize) )
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return -1;
|
||||
}
|
||||
memcpy(udrs->putbytes, (char*)object_p, size);
|
||||
udrs->putbytes += size;
|
||||
if(udrs->putbytes > udrs->putend) udrs->putend = udrs->putbytes;
|
||||
}
|
||||
else if(udrs->udr_op == UDR_DECODE)
|
||||
{
|
||||
if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size )
|
||||
{ /* need more data in character stream buffer */
|
||||
remain = (UDIUInt32)(udrs->bufsize) -
|
||||
( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->buff) );
|
||||
if( ((UDIUInt32)(udrs->bufsize) + (UDIUInt32)(udrs->buff)
|
||||
- (UDIUInt32)(udrs->getbytes)) < size)
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return -1;
|
||||
}
|
||||
cnt = read(udrs->sd, (char*)udrs->putbytes, remain);
|
||||
if(cnt == -1) perror("ERROR udr_work(), read() failure: ");
|
||||
udrs->putbytes += cnt;
|
||||
if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size )
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return -1; /* return error code */
|
||||
}
|
||||
} /* read data from character stream buffer */
|
||||
memcpy((char*)object_p, udrs->getbytes, size);
|
||||
udrs->getbytes += size;
|
||||
}
|
||||
else
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************* UDR_UDIResource
|
||||
*/
|
||||
int udr_UDIResource(udrs, object_p)
|
||||
UDR* udrs;
|
||||
UDIResource* object_p;
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = udr_CPUSpace(udrs, &object_p->Space);
|
||||
retval = retval | udr_CPUOffset(udrs, &object_p->Offset);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**************************************************************** UDR_UDIRange
|
||||
*/
|
||||
int udr_UDIRange(udrs, object_p)
|
||||
UDR* udrs;
|
||||
UDIRange* object_p;
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = udr_CPUOffset(udrs, &object_p->Low);
|
||||
retval = retval | udr_CPUOffset(udrs, &object_p->High);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/********************************************************** UDR_UDIMemoryRange
|
||||
*/
|
||||
int udr_UDIMemoryRange(udrs, object_p)
|
||||
UDR* udrs;
|
||||
UDIMemoryRange* object_p;
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = udr_CPUSpace(udrs, &object_p->Space);
|
||||
retval = retval | udr_CPUOffset(udrs, &object_p->Offset);
|
||||
retval = retval | udr_CPUSizeT(udrs, &object_p->Size);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/****************************************************************** UDR_string
|
||||
*/
|
||||
int udr_string(udrs, sp)
|
||||
UDR* udrs;
|
||||
char* sp;
|
||||
{
|
||||
int len, retval;
|
||||
|
||||
if(udrs->udr_op == UDR_ENCODE)
|
||||
{
|
||||
if(sp)
|
||||
{ len = strlen(sp) + 1;
|
||||
retval = udr_UDIInt32(udrs, &len);
|
||||
retval = retval | udr_work(udrs, sp, len);
|
||||
}
|
||||
else /* deal with NULL pointer */
|
||||
{ len = 0;
|
||||
retval = udr_UDIInt32(udrs, &len);
|
||||
}
|
||||
}
|
||||
else if(udrs->udr_op == UDR_DECODE)
|
||||
{
|
||||
retval = udr_UDIInt32(udrs, &len);
|
||||
if(len)
|
||||
retval = retval | udr_work(udrs, sp, len);
|
||||
else *sp = '\0'; /* terminate string */
|
||||
}
|
||||
else
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/******************************************************************* UDR_BYTES
|
||||
*/
|
||||
int udr_bytes(udrs, ptr, len)
|
||||
UDR* udrs;
|
||||
char* ptr;
|
||||
int len;
|
||||
{
|
||||
return udr_work(udrs, ptr, len);
|
||||
}
|
||||
|
||||
/********************************************************************* UDR_INT
|
||||
*/
|
||||
int udr_int(udrs, int_p)
|
||||
UDR* udrs;
|
||||
int* int_p;
|
||||
{
|
||||
int ret_val;
|
||||
UDIInt32 udr_obj; /* object of know size */
|
||||
|
||||
if(udrs->udr_op == UDR_ENCODE)
|
||||
{
|
||||
udr_obj = *int_p; /* copy into know object size */
|
||||
return udr_UDIInt32(udrs, &udr_obj);
|
||||
}
|
||||
else if(udrs->udr_op == UDR_DECODE)
|
||||
{
|
||||
ret_val = udr_UDIInt32(udrs, &udr_obj); /* get object of known size */
|
||||
*int_p = udr_obj;
|
||||
return ret_val;
|
||||
}
|
||||
else
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************** UDR_INLINE
|
||||
*/
|
||||
char* udr_inline(udrs, size)
|
||||
UDR* udrs;
|
||||
int size;
|
||||
{
|
||||
if(udrs->udr_op != udrs->previous_op)
|
||||
{ if(udrs->previous_op == 0)
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return 0;
|
||||
}
|
||||
udrs->previous_op= udrs->udr_op;
|
||||
udrs->putbytes = udrs->buff;
|
||||
udrs->getbytes = udrs->buff;
|
||||
}
|
||||
if(udrs->udr_op == UDR_ENCODE)
|
||||
{
|
||||
if(udrs->putbytes + size > udrs->bufsize + udrs->buff)
|
||||
return 0;
|
||||
udrs->putbytes += size;
|
||||
return udrs->putbytes - size;
|
||||
}
|
||||
else if(udrs->udr_op == UDR_DECODE)
|
||||
{
|
||||
if(udrs->getbytes + size > udrs->bufsize + udrs->buff)
|
||||
return 0;
|
||||
udrs->getbytes += size;
|
||||
return udrs->getbytes - size;
|
||||
}
|
||||
else
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************** UDR_GETPOS
|
||||
*/
|
||||
char* udr_getpos(udrs)
|
||||
UDR* udrs;
|
||||
{
|
||||
if(udrs->udr_op == UDR_ENCODE)
|
||||
{
|
||||
return udrs->putbytes;
|
||||
}
|
||||
else if(udrs->udr_op == UDR_DECODE)
|
||||
{
|
||||
return udrs->getbytes;
|
||||
}
|
||||
else
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************** UDR_SETPOS
|
||||
*/
|
||||
int udr_setpos(udrs, pos)
|
||||
UDR* udrs;
|
||||
char* pos;
|
||||
{
|
||||
if( ((UDIUInt32)pos > (UDIUInt32)(udrs->buff) + (UDIUInt32)(udrs->bufsize))
|
||||
|| ((UDIUInt32)pos < (UDIUInt32)(udrs->buff) ) )
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return 0;
|
||||
}
|
||||
if(udrs->udr_op == UDR_ENCODE)
|
||||
{
|
||||
udrs->putbytes = pos;
|
||||
return 1;
|
||||
}
|
||||
else if(udrs->udr_op == UDR_DECODE)
|
||||
{
|
||||
udrs->getbytes = pos;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************** UDR_READNOW
|
||||
* Try and ensure "size" bytes are available in the
|
||||
* receive buffer character stream.
|
||||
*/
|
||||
int udr_readnow(udrs, size)
|
||||
UDR* udrs;
|
||||
int size;
|
||||
{
|
||||
int cnt, remain;
|
||||
|
||||
if(udrs->udr_op == UDR_ENCODE)
|
||||
{
|
||||
udr_errno = UDIErrorIPCInternal;
|
||||
return -1;
|
||||
}
|
||||
else if(udrs->udr_op == UDR_DECODE)
|
||||
{
|
||||
if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size )
|
||||
{ /* need more data in character stream buffer */
|
||||
remain = (UDIUInt32)(udrs->bufsize) -
|
||||
( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->buff) );
|
||||
cnt = read(udrs->sd, (char*)udrs->putbytes, remain);
|
||||
if(cnt == -1) perror("ERROR udr_work(), read() failure: ");
|
||||
udrs->putbytes += cnt;
|
||||
if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size )
|
||||
{ fprintf(stderr,"ERROR, udr_readnow() too few bytes in stream\n");
|
||||
return -1; /* return error code */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ udr_errno = UDIErrorIPCInternal;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************* UDR_ALIGN
|
||||
*/
|
||||
int udr_align(udrs, size)
|
||||
UDR* udrs;
|
||||
int size;
|
||||
{
|
||||
char* align;
|
||||
int offset;
|
||||
|
||||
align = udr_getpos(udrs);
|
||||
offset = size - ((int)align & (size -1));
|
||||
offset = offset & (size -1);
|
||||
if(offset) udr_setpos(udrs, align + offset);
|
||||
}
|
||||
#endif /* __GO32__ */
|
||||
@@ -1,9 +0,0 @@
|
||||
# @(#)udi_soc 2.1 Daniel Mann
|
||||
# NOTE: the Session string must not start whith white-space characters.
|
||||
# Format of string is:
|
||||
# <session> <domain> <soc_name|host_name> <tip_exe> <pass to UDIconnect>
|
||||
soc2cayman AF_INET cayman /bin/udi_tip ...
|
||||
soc2tip AF_UNIX astring tip.exe ...
|
||||
cuba AF_UNIX soc_name ../bin.68020/udi_tip stuff to pass
|
||||
cayman AF_INET cayman this_entry_not_matter stuff to pass
|
||||
iss AF_UNIX * sun4/isstip -r osboot
|
||||
143
gdb/CONTRIBUTE
143
gdb/CONTRIBUTE
@@ -1,143 +0,0 @@
|
||||
|
||||
Contributing to GDB
|
||||
|
||||
GDB is a collaborative project and one which wants to encourage new
|
||||
development. You may wish to fix GDB bugs, improve testing, port GDB
|
||||
to a new platform, update documentation, add new GDB features, and the
|
||||
like. To help with this, there is a lot of documentation
|
||||
available.. In addition to the user guide and internals manual
|
||||
included in the GDB distribution, the GDB web pages also contain much
|
||||
information.
|
||||
|
||||
You may also want to submit your change so that can be considered for
|
||||
conclusion in a future version of GDB (see below). Regardless, we
|
||||
encourage you to distribute the change yourself.
|
||||
|
||||
If you don't feel up to hacking GDB, there are still plenty of ways to
|
||||
help! You can answer questions on the mailing lists, write
|
||||
documentation, find bugs, create a GDB related website (contribute to
|
||||
the official GDB web site), or create a GDB related software
|
||||
package. We welcome all of the above and feel free to ask on the GDB
|
||||
mailing lists if you are looking for feedback or for people to review
|
||||
a work in progress.
|
||||
|
||||
Ref: http://www.gnu.org/software/gdb/
|
||||
|
||||
Finally, there are certain legal requirements and style issues which
|
||||
all contributors need to be aware of.
|
||||
|
||||
o Coding Standards
|
||||
|
||||
All contributions must conform to the GNU Coding Standard.
|
||||
Submissions which do not conform to the standards will be
|
||||
returned with a request to reformat the changes.
|
||||
|
||||
GDB has certain additional coding requirements. Those
|
||||
requirements are explained in the GDB internals documentation
|
||||
in the gdb/doc directory.
|
||||
|
||||
Ref: http://www.gnu.org/prep/standards_toc.html
|
||||
|
||||
|
||||
o Copyright Assignment
|
||||
|
||||
Before we can accept code contributions from you, we need a
|
||||
copyright assignment form filled out and filed with the FSF.
|
||||
|
||||
See some documentation by the FSF for details and contact us
|
||||
(either via the GDB mailing list or the GDB maintainer that is
|
||||
taking care of your contributions) to obtain the relevant
|
||||
forms.
|
||||
|
||||
Small changes can be accepted without a copyright assignment form on file.
|
||||
|
||||
Ref: http://www.gnu.org/prep/maintain.html#SEC6
|
||||
|
||||
|
||||
o Submitting Patches
|
||||
|
||||
Every patch must have several pieces of information before we
|
||||
can properly evaluate it.
|
||||
|
||||
A description of the bug and how your patch fixes this
|
||||
bug. A reference to a testsuite failure is very helpful. For
|
||||
new features a description of the feature and your
|
||||
implementation.
|
||||
|
||||
A ChangeLog entry as plaintext (separate from the patch); see
|
||||
the various ChangeLog files for format and content. Note that,
|
||||
unlike some other projects, we do require ChangeLogs also for
|
||||
documentation (i.e., .texi files).
|
||||
|
||||
The patch itself. If you are accessing the CVS repository use
|
||||
"cvs update; cvs diff -c3p"; else, use "diff -c3p OLD NEW" or
|
||||
"diff -up OLD NEW". If your version of diff does not support
|
||||
these options, then get the latest version of GNU diff.
|
||||
|
||||
We accept patches as plain text (preferred for the compilers
|
||||
themselves), MIME attachments (preferred for the web pages),
|
||||
or as uuencoded gzipped text.
|
||||
|
||||
When you have all these pieces, bundle them up in a mail
|
||||
message and send it to gdb-patches@sources.redhat.com. All
|
||||
patches and related discussion should be sent to the
|
||||
gdb-patches mailinglist. For further information on the GDB
|
||||
CVS repository, see the Anonymous read-only CVS access and
|
||||
Read-write CVS access page.
|
||||
|
||||
--
|
||||
|
||||
Supplemental information for GDB:
|
||||
|
||||
o Please try to run the relevant testsuite before and after
|
||||
committing a patch
|
||||
|
||||
If the contributor doesn't do it then the maintainer will. A
|
||||
contributor might include before/after test results in their
|
||||
contribution.
|
||||
|
||||
|
||||
o For bug fixes, please try to include a way of
|
||||
demonstrating that the patch actually fixes something.
|
||||
|
||||
The best way of doing this is to ensure that the
|
||||
testsuite contains one or more test cases that
|
||||
fail without the fix but pass with the fix.
|
||||
|
||||
People are encouraged to submit patches that extend
|
||||
the testsuite.
|
||||
|
||||
|
||||
o Please read your patch before submitting it.
|
||||
|
||||
A patch containing several unrelated changes or
|
||||
arbitrary reformats will be returned with a request
|
||||
to re-formatting / split it.
|
||||
|
||||
|
||||
o If ``gdb/configure.in'' is modified then you don't
|
||||
need to include patches to the regenerated file
|
||||
``configure''.
|
||||
|
||||
The maintainer will re-generate those files
|
||||
using autoconf (2.13 as of 2000-02-29).
|
||||
|
||||
|
||||
o If ``gdb/gdbarch.sh'' is modified, you don't
|
||||
need to include patches to the generated files
|
||||
``gdbarch.h'' and ``gdbarch.c''.
|
||||
|
||||
See ``gdb/configure.in'' above.
|
||||
|
||||
|
||||
o When submitting a patch that fixes a bug
|
||||
in GDB's bug database a brief reference
|
||||
to the bug can be included in the ChangeLog
|
||||
vis
|
||||
|
||||
* CONTRIBUTE: Mention PR convention.
|
||||
Fix PR gdb/4705.
|
||||
|
||||
The text ``PR gdb/4705'' should also be included
|
||||
in the CVS commit message. That causes the
|
||||
patch to automatically be archived with the PR.
|
||||
340
gdb/COPYING
340
gdb/COPYING
@@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
1848
gdb/ChangeLog
1848
gdb/ChangeLog
File diff suppressed because it is too large
Load Diff
3155
gdb/ChangeLog-1990
3155
gdb/ChangeLog-1990
File diff suppressed because it is too large
Load Diff
5175
gdb/ChangeLog-1991
5175
gdb/ChangeLog-1991
File diff suppressed because it is too large
Load Diff
6285
gdb/ChangeLog-1992
6285
gdb/ChangeLog-1992
File diff suppressed because it is too large
Load Diff
7597
gdb/ChangeLog-1993
7597
gdb/ChangeLog-1993
File diff suppressed because it is too large
Load Diff
5705
gdb/ChangeLog-1994
5705
gdb/ChangeLog-1994
File diff suppressed because it is too large
Load Diff
4915
gdb/ChangeLog-1995
4915
gdb/ChangeLog-1995
File diff suppressed because it is too large
Load Diff
5116
gdb/ChangeLog-1996
5116
gdb/ChangeLog-1996
File diff suppressed because it is too large
Load Diff
2909
gdb/ChangeLog-1997
2909
gdb/ChangeLog-1997
File diff suppressed because it is too large
Load Diff
7220
gdb/ChangeLog-1998
7220
gdb/ChangeLog-1998
File diff suppressed because it is too large
Load Diff
9296
gdb/ChangeLog-1999
9296
gdb/ChangeLog-1999
File diff suppressed because it is too large
Load Diff
8204
gdb/ChangeLog-2000
8204
gdb/ChangeLog-2000
File diff suppressed because it is too large
Load Diff
9895
gdb/ChangeLog-2001
9895
gdb/ChangeLog-2001
File diff suppressed because it is too large
Load Diff
4838
gdb/ChangeLog-3.x
4838
gdb/ChangeLog-3.x
File diff suppressed because it is too large
Load Diff
415
gdb/MAINTAINERS
415
gdb/MAINTAINERS
@@ -1,415 +0,0 @@
|
||||
GDB Maintainers
|
||||
|
||||
|
||||
Blanket Write Privs
|
||||
(alphabetic)
|
||||
|
||||
Jim Blandy jimb@redhat.com
|
||||
Kevin Buettner kevinb@redhat.com
|
||||
Andrew Cagney ac131313@redhat.com
|
||||
J.T. Conklin jtc@redback.com
|
||||
Fred Fish fnf@ninemoons.com
|
||||
Mark Kettenis kettenis@gnu.org
|
||||
Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de
|
||||
Stan Shebs shebs@apple.com
|
||||
Michael Snyder msnyder@redhat.com
|
||||
Elena Zannoni ezannoni@redhat.com
|
||||
Eli Zaretskii eliz@gnu.org
|
||||
|
||||
|
||||
Various Maintainers
|
||||
|
||||
Note individuals who maintain parts of the debugger need approval to
|
||||
check in changes outside of the immediate domain that they maintain.
|
||||
|
||||
If there is no maintainer for a given domain then the responsibility
|
||||
falls to the head maintainer.
|
||||
|
||||
If there are several maintainers for a given domain then
|
||||
responsibility falls to the first maintainer. The first maintainer is
|
||||
free to devolve that responsibility among the other maintainers.
|
||||
|
||||
|
||||
The Obvious Fix Rule
|
||||
|
||||
All maintainers listed in this file are allowed to check in obvious
|
||||
fixes.
|
||||
|
||||
An "obvious fix" means that there is no possibility that anyone will
|
||||
disagree with the change.
|
||||
|
||||
A good mental test is "will the person who hates my work the most be
|
||||
able to find fault with the change" - if so, then it's not obvious and
|
||||
needs to be posted first. :-)
|
||||
|
||||
Something like changing or bypassing an interface is _not_ an obvious
|
||||
fix, since such a change without discussion will result in
|
||||
instantaneous and loud complaints.
|
||||
|
||||
|
||||
Target/Architecture:
|
||||
|
||||
Generic ISA (Instruction Set Architecture) issues, API variants, CPU
|
||||
variants. *-tdep.c. The Target/Architecture maintainer works with the
|
||||
host maintainer when resolving build issues. The Target/Architecture
|
||||
maintainer works with the native maintainer when resolving API issues.
|
||||
|
||||
a29k OBSOLETE
|
||||
|
||||
alpha --target=alpha-dec-osf4.0a -Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
arc --target=arc-elf ,-Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
arm --target=arm-elf -w
|
||||
Fernando Nasser fnasser@redhat.com
|
||||
Scott Bambrough scottb@netwinder.org
|
||||
Richard Earnshaw rearnsha@arm.com
|
||||
Not multi-arch
|
||||
|
||||
cris --target=cris-elf -w
|
||||
Orjan Friberg orjanf@axis.com
|
||||
|
||||
d10v --target=d10v-elf ,-Werror
|
||||
Maintenance only
|
||||
|
||||
d30v --target=d30v-elf ,-Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
djgpp --target=i586-pc-msdosdjgpp ,-Werror
|
||||
(See native and host)
|
||||
|
||||
fr30 --target=fr30-elf -Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
h8300 --target=h8300hms -Werror
|
||||
Maintenance only
|
||||
Not multi-arch, work in progress
|
||||
|
||||
h8500 --target=h8500hms -Werror
|
||||
Maintenance only
|
||||
Not multi-arch, work in progress
|
||||
|
||||
i386 --target=i386-elf,i386-aout ,-Werror
|
||||
Mark Kettenis kettenis@gnu.org
|
||||
|
||||
i960 --target=i960-coff ,-Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
ia64 --target=ia64-linux ,-Werror
|
||||
Kevin Buettner kevinb@redhat.com
|
||||
|
||||
m32r --target=m32r-elf -Werror
|
||||
Michael Snyder msnyder@redhat.com
|
||||
Not multi-arch
|
||||
|
||||
m68hc11 --target=m68hc11-elf ,-Werror
|
||||
Stephane Carrez Stephane.Carrez@worldnet.fr
|
||||
|
||||
m68k --target=m68k-elf ,-Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
m88k --target=m88k ,-Werror
|
||||
Known problem in 5.1
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
mcore --target=mcore-elf,mcore-pe ,-Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
mips --target=mips-elf,mips64-elf ,-Werror
|
||||
Andrew Cagney cagney@redhat.com
|
||||
|
||||
mn10200 --target=mn10200-elf ,-Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
mn10300 --target=mn10300-elf ,-Werror
|
||||
Maintenance only
|
||||
|
||||
ns32k --target=ns32k-netbsd ,-Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
pa (--target=hppa1.1-hp-proelf broken)
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
powerpc --target=powerpc-eabi ,-Werror
|
||||
Kevin Buettner kevinb@redhat.com
|
||||
|
||||
rs6000 --target=rs6000-ibm-aix4.1 ,-Werror
|
||||
(see rs6000 native and ppc target)
|
||||
|
||||
s390 --target=s390-linux ,-Werror
|
||||
(contact DJ Barrow djbarrow@de.ibm.com)
|
||||
|
||||
sh --target=sh-hms,sh-elf ,-Werror
|
||||
Elena Zannoni ezannoni@redhat.com
|
||||
|
||||
sparc --target=sparc-elf,sparc64-elf ,-Werror
|
||||
Maintenance only
|
||||
|
||||
tic80 Deleted.
|
||||
|
||||
v850 --target=v850-elf ,-Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
vax --target=vax-dec-vms5.5 ,-Werror
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
w65 Deleted.
|
||||
|
||||
xstormy16 --target=xstormy16-elf ,-Werror
|
||||
Corinna Vinschen vinschen@redhat.com
|
||||
|
||||
z8k --target=z8k-coff ,-Werror
|
||||
Known problem in 5.1
|
||||
Maintenance only
|
||||
OBSOLETE candidate, not multi-arch
|
||||
|
||||
All developers recognized by this file can make arbitrary changes to
|
||||
OBSOLETE targets.
|
||||
|
||||
All maintainers can test and thence approve non-trivial changes to
|
||||
``maintenance only'' targets submitted by recognized developers.
|
||||
|
||||
All recognized developers can make mechanical changes (by virtue of
|
||||
the obvious fix rule) to ``maintenance only'' targets. The change
|
||||
shall be sanity checked by compiling with one of the listed targets.
|
||||
|
||||
The GAWK segment:
|
||||
|
||||
awk < "${maintainers}" '
|
||||
$2 ~ /--target=.*/ {
|
||||
targets = gensub (/^.*--target=/, "", 1, $2)
|
||||
warnings = gensub (/[)]*$/, "", 1, $3)
|
||||
split (targets, targ, /,/)
|
||||
for (i in targ) {
|
||||
print targ[i], warnings
|
||||
}
|
||||
}'
|
||||
|
||||
can be used to generate a full list of --target=
|
||||
--enable-gdb-build-warning= pairs.
|
||||
|
||||
|
||||
|
||||
Host/Native:
|
||||
|
||||
The Native maintainer is responsible for target specific native
|
||||
support - typically shared libraries and quirks to procfs/ptrace/...
|
||||
The Native maintainer works with the Arch and Core maintainers when
|
||||
resolving more generic problems.
|
||||
|
||||
The host maintainer ensures that gdb (including mmalloc) can be built
|
||||
as a cross debugger on their platform.
|
||||
|
||||
AIX Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de
|
||||
Kevin Buettner kevinb@redhat.com
|
||||
|
||||
djgpp native Eli Zaretskii eliz@gnu.org
|
||||
DJ Delorie dj@redhat.com
|
||||
MS Windows (NT, CE, '00, 9x, Me) host & native
|
||||
Chris Faylor cgf@redhat.com
|
||||
GNU/Linux/x86 native & host
|
||||
Mark Kettenis kettenis@gnu.org
|
||||
Jim Blandy jimb@redhat.com
|
||||
GNU/Linux PPC native Kevin Buettner kevinb@redhat.com
|
||||
GNU/Linux MIPS native & host
|
||||
Daniel Jacobowitz dan@debian.org
|
||||
GNU/Linux m68k Andreas Schwab schwab@suse.de
|
||||
FreeBSD native & host Mark Kettenis kettenis@gnu.org
|
||||
David O'Brien obrien@freebsd.org
|
||||
hurd native Mark Kettenis kettenis@gnu.org
|
||||
NetBSD native & host J.T. Conklin jtc@redback.com
|
||||
SCO/Unixware Robert Lipe rjl@sco.com
|
||||
GNU/Linux ARM native Scott Bambrough scottb@netwinder.org
|
||||
Solaris/x86 native & host (devolved)
|
||||
Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de
|
||||
Solaris/SPARC native & host (devolved)
|
||||
Michael Snyder msnyder@redhat.com
|
||||
Mac OS X Klee Dienes kdienes@apple.com
|
||||
Jim Ingham jingham@apple.com
|
||||
|
||||
|
||||
|
||||
Core: Generic components used by all of GDB
|
||||
|
||||
generic arch support Andrew Cagney cagney@redhat.com
|
||||
Any host/target maintainer can add to
|
||||
gdbarch.{c,h,sh}. Send tricky ones to cagney.
|
||||
target vector Andrew Cagney cagney@redhat.com
|
||||
main (main.c, top.c) Elena Zannoni ezannoni@redhat.com
|
||||
event loop Elena Zannoni ezannoni@redhat.com
|
||||
|
||||
generic symtabs Jim Blandy jimb@redhat.com
|
||||
Elena Zannoni ezannoni@redhat.com
|
||||
dwarf readers Jim Blandy jimb@redhat.com
|
||||
Elena Zannoni ezannoni@redhat.com
|
||||
elf reader Jim Blandy jimb@redhat.com
|
||||
Elena Zannoni ezannoni@redhat.com
|
||||
stabs reader Jim Blandy jimb@redhat.com
|
||||
Elena Zannoni ezannoni@redhat.com
|
||||
coff reader Philippe De Muyter phdm@macqel.be
|
||||
xcoff reader Any maintainer can modify this; please send tricky
|
||||
ones to Kevin Buettner <kevinb@redhat.com>
|
||||
linespec Jim Blandy jimb@redhat.com
|
||||
Elena Zannoni ezannoni@redhat.com
|
||||
Fernando Nasser fnasser@redhat.com
|
||||
|
||||
tracing bytecode stuff Jim Blandy jimb@redhat.com
|
||||
tracing Michael Snyder msnyder@redhat.com
|
||||
threads Michael Snyder msnyder@redhat.com
|
||||
Mark Kettenis kettenis@gnu.org
|
||||
breakpoints Michael Snyder msnyder@redhat.com
|
||||
Jim Blandy jimb@redhat.com
|
||||
language support (Blanket Write Privs Maintainers)
|
||||
C++ Daniel Jacobowitz dan@debian.org
|
||||
Java support (devolved)
|
||||
Per Bothner per@bothner.com
|
||||
Anthony Green green@redhat.com
|
||||
Objective-C/C++ Klee Dienes kdienes@apple.com
|
||||
Jim Ingham jimgham@apple.com
|
||||
Pascal support Pierre Muller muller@sourceware.redhat.com
|
||||
Scheme support Jim Blandy jimb@redhat.com
|
||||
|
||||
shared libs (devolved) Jim Blandy jimb@redhat.com
|
||||
Kevin Buettner kevinb@redhat.com
|
||||
xcoffsolib Peter Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de
|
||||
|
||||
remote.c Andrew Cagney cagney@redhat.com
|
||||
J.T. Conklin jtc@redback.com
|
||||
include/remote-sim.h, remote-sim.c
|
||||
Andrew Cagney cagney@redhat.com
|
||||
sds protocol Fernando Nasser fnasser@redhat.com
|
||||
rdi/adp protocol Fernando Nasser fnasser@redhat.com
|
||||
documentation Eli Zaretskii eliz@gnu.org
|
||||
testsuite Fernando Nasser fnasser@redhat.com
|
||||
config Mark Salter msalter@redhat.com
|
||||
lib Mark Salter msalter@redhat.com
|
||||
gdbtk (gdb.gdbtk) Keith Seitz keiths@redhat.com
|
||||
c++ (gdb.c++) Michael Chastain mec@shout.net
|
||||
mi tests (gdb.mi) Elena Zannoni ezannoni@redhat.com
|
||||
Andrew Cagney cagney@redhat.com
|
||||
stabs (gdb.satbs) Elena Zannoni ezannoni@redhat.com
|
||||
threads (gdb.threads) Michael Snyder msnyder@redhat.com
|
||||
trace (gdb.trace) Michael Snyder msnyder@redhat.com
|
||||
hp tests (gdb.hp) (vacant)
|
||||
Java tests (gdb.java) Anthony Green green@redhat.com
|
||||
Kernel Object Display Fernando Nasser fnasser@redhat.com
|
||||
dcache.c J.T. Conklin jtc@redback.com
|
||||
|
||||
|
||||
UI: External (user) interfaces.
|
||||
|
||||
command interpreter Fernando Nasser fnasser@redhat.com
|
||||
gdbtk (c & tcl) Jim Ingham jingham@apple.com
|
||||
Fernando Nasser fnasser@redhat.com
|
||||
Keith Seitz keiths@redhat.com
|
||||
libgui (w/foundry, sn) Jim Ingham jingham@apple.com
|
||||
Keith Seitz keiths@redhat.com
|
||||
mi (gdb/mi) Andrew Cagney cagney@redhat.com
|
||||
Elena Zannoni ezannoni@redhat.com
|
||||
Fernando Nasser fnasser@redhat.com
|
||||
tui (vacant)
|
||||
Technical Contact Point wdb@cup.hp.com
|
||||
|
||||
|
||||
Misc:
|
||||
|
||||
Web pages. Jim Kingdon jkingdon@engr.sgi.com ++
|
||||
(anyone can edit; kingdon is just lead maintainer)
|
||||
|
||||
Makefile.in, configure* ALL
|
||||
|
||||
mmalloc/ ALL Host maintainers
|
||||
|
||||
sim/ See sim/MAINTAINERS, co-ordinated by:
|
||||
Frank Ch. Eigler fche@redhat.com
|
||||
|
||||
readline/ Master version: ftp://ftp.cwru.edu/pub/bash/
|
||||
Elena Zannoni ezannoni@redhat.com
|
||||
Host maintainers (host dependant parts)
|
||||
(but get your changes into the master version)
|
||||
|
||||
tcl/ tk/ itcl/ Ian Roxborough irox@redhat.com
|
||||
|
||||
Write After Approval
|
||||
(alphabetic)
|
||||
|
||||
To get recommended for the Write After Approval list you need a valid
|
||||
FSF assignment and have submitted one good patch.
|
||||
|
||||
David Anderson davea@sgi.com
|
||||
Philip Blundell philb@gnu.org
|
||||
Joel Brobecker brobecker@act-europe.fr
|
||||
Nick Clifton nickc@redhat.com
|
||||
Chris G. Demetriou cgd@broadcom.com
|
||||
Richard Earnshaw rearnsha@arm.com
|
||||
Matthew Green mrg@eterna.com.au
|
||||
Orjan Friberg orjanf@axis.com
|
||||
Ben Harris bjh21@netbsd.org
|
||||
Paul Hilfinger hilfinger@gnat.com
|
||||
Matt Hiller hiller@redhat.com
|
||||
Kazu Hirata kazu@hxi.com
|
||||
Jeff Holcomb jeffh@redhat.com
|
||||
Don Howard dhoward@redhat.com
|
||||
Martin Hunt hunt@redhat.com
|
||||
Daniel Jacobowitz dan@debian.org
|
||||
Andreas Jaeger aj@suse.de
|
||||
Geoff Keating geoffk@redhat.com
|
||||
Jim Kingdon jkingdon@engr.sgi.com ++
|
||||
Jonathan Larmour jlarmour@redhat.co.uk
|
||||
H.J. Lu hjl@lucon.org
|
||||
Glen McCready gkm@redhat.com
|
||||
Jason Merrill jason@redhat.com
|
||||
Jason Molenda jmolenda@apple.com
|
||||
Pierre Muller muller@sourceware.redhat.com
|
||||
Alexandre Oliva aoliva@redhat.com
|
||||
Tom Rix trix@redhat.com
|
||||
Mark Salter msalter@redhat.com
|
||||
Andreas Schwab schwab@suse.de
|
||||
Keith Seitz keiths@redhat.com
|
||||
Jiri Smid smid@suse.cz
|
||||
David Smith dsmith@redhat.com
|
||||
Stephen P. Smith ischis2@home.com
|
||||
Jackie Smith Cashion jsmith@redhat.com
|
||||
Petr Sorfa petrs@caldera.com
|
||||
Gary Thomas gthomas@redhat.com
|
||||
Jason Thorpe thorpej@wasabisystems.com
|
||||
Tom Tromey tromey@redhat.com
|
||||
Corinna Vinschen vinschen@redhat.com
|
||||
Keith Walker keith.walker@arm.com
|
||||
|
||||
|
||||
|
||||
Past Maintainers
|
||||
|
||||
Jimmy Guo (gdb.hp, tui) guo@cup.hp.com
|
||||
Jeff Law (hppa) law@cygnus.com
|
||||
Daniel Berlin (C++ support) dan@cgsoftware.com
|
||||
Nick Duffek (powerpc, SCO, Sol/x86) nick at duffek dot com
|
||||
David Taylor (d10v, sparc, utils, defs,
|
||||
expression evaluator, language support) taylor at candd dot org
|
||||
|
||||
|
||||
Folks that have been caught up in a paper trail:
|
||||
|
||||
Jim Kingdon jkingdon@engr.sgi.com
|
||||
Michael Chastain mec@shout.net
|
||||
|
||||
--
|
||||
|
||||
(*) Indicates folks that don't have a Kerberos/SSH account in the GDB
|
||||
group.
|
||||
2340
gdb/Makefile.in
2340
gdb/Makefile.in
File diff suppressed because it is too large
Load Diff
59
gdb/PROBLEMS
59
gdb/PROBLEMS
@@ -1,59 +0,0 @@
|
||||
Known problems in GDB 5.1.1
|
||||
|
||||
|
||||
See also the bug database http://www.gnu.org/software/gdb/bugs/
|
||||
|
||||
|
||||
Contrary to the GDB 5.1.1 announcement, the update did not contain
|
||||
fixes to a i386 floating point problem. The latest sources do contain
|
||||
the fix and it will be included in GDB 5.2.
|
||||
|
||||
|
||||
Known problems in GDB 5.1
|
||||
|
||||
|
||||
hppa2.0-hp-hpux10.20
|
||||
|
||||
Due to a problem (conflicting types) with libiberty/regex.c, GDB 5.1
|
||||
does not build on HP/UX 10.20 when using the HP supplied compiler.
|
||||
|
||||
Due to bit rot, GDB 5.1 does not work on HP/UX 10.20 when built with
|
||||
GCC.
|
||||
|
||||
|
||||
hppa2.0w-hp-hpux11.00
|
||||
|
||||
Due to a problem with ltconfig and long argument lines, GDB 5.1 does
|
||||
not configure on HP/UX 11.00.
|
||||
|
||||
|
||||
alpha-dec-osf5.1
|
||||
|
||||
GDB 5.1 has a number of problems on this platform (Ref PR gdb/237). A
|
||||
GDB 5.1 built with ``CC="cc -DUSE_LDR_ROUTINES"'' is reported to work
|
||||
much better.
|
||||
|
||||
|
||||
alpha-dec-osf4.0e
|
||||
|
||||
GDB 5.1 is known to have problems on this platform (encounters an
|
||||
internal error in the symbol table reader).
|
||||
|
||||
|
||||
sparcv9-sun-solaris2.8
|
||||
|
||||
There are known problems with building GDB 5.1 using GCC 3.0.x for the
|
||||
64 bit SPARC target (bad code gen). You could try a development
|
||||
version of GCC.
|
||||
|
||||
|
||||
i586-sco-sysv5uw7.1.1
|
||||
|
||||
There are known problems with GDB 5.1's thread support on this
|
||||
platform. Non-threaded programs should work.
|
||||
|
||||
|
||||
*-*-*
|
||||
|
||||
GDB 5.1 assumes that the host C compiler implemends alloca(). GCC is
|
||||
one such compiler. This problem should be fixed on the trunk.
|
||||
569
gdb/README
569
gdb/README
@@ -1,569 +0,0 @@
|
||||
README for gdb-5.1.1 release
|
||||
Updated 23 January, 2002 by Andrew Cagney
|
||||
|
||||
This is GDB, the GNU source-level debugger.
|
||||
A summary of new features is in the file `NEWS'.
|
||||
|
||||
See the GDB home page at http://www.gnu.org/software/gdb/ for up to
|
||||
date release information, mailing list links and archives, etc.
|
||||
|
||||
See the file PROBLEMS for late breaking news.
|
||||
|
||||
|
||||
Unpacking and Installation -- quick overview
|
||||
==========================
|
||||
|
||||
In this release, the GDB debugger sources, the generic GNU include
|
||||
files, the BFD ("binary file description") library, the readline
|
||||
library, and other libraries all have directories of their own
|
||||
underneath the gdb-5.1.1 directory. The idea is that a variety of GNU
|
||||
tools can share a common copy of these things. Be aware of variation
|
||||
over time--for example don't try to build gdb with a copy of bfd from
|
||||
a release other than the gdb release (such as a binutils release),
|
||||
especially if the releases are more than a few weeks apart.
|
||||
Configuration scripts and makefiles exist to cruise up and down this
|
||||
directory tree and automatically build all the pieces in the right
|
||||
order.
|
||||
|
||||
When you unpack the gdb-5.1.1.tar.gz file, you'll find a directory
|
||||
called `gdb-5.1.1', which contains:
|
||||
|
||||
COPYING config.sub intl missing opcodes
|
||||
COPYING.LIB configure libiberty mkinstalldirs readline
|
||||
Makefile.in configure.in libtool.m4 mmalloc sim
|
||||
README djunpack.bat ltcf-c.sh move-if-change symlink-tree
|
||||
bfd etc ltcf-cxx.sh mpw-README texinfo
|
||||
config gdb ltcf-gcj.sh mpw-build.in utils
|
||||
config-ml.in gettext.m4 ltconfig mpw-config.in ylwrap
|
||||
config.guess include ltmain.sh mpw-configure
|
||||
config.if install-sh md5.sum mpw-install
|
||||
|
||||
You can build GDB right in the source directory:
|
||||
|
||||
cd gdb-5.1.1
|
||||
./configure
|
||||
make
|
||||
cp gdb/gdb /usr/local/bin/gdb (or wherever you want)
|
||||
|
||||
However, we recommend that an empty directory be used instead.
|
||||
This way you do not clutter your source tree with binary files
|
||||
and will be able to create different builds with different
|
||||
configuration options.
|
||||
|
||||
You can build GDB in any empty build directory:
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
<full path to your sources>/gdb-5.1.1/configure
|
||||
make
|
||||
cp gdb/gdb /usr/local/bin/gdb (or wherever you want)
|
||||
|
||||
(Building GDB with DJGPP tools for MS-DOS/MS-Windows is slightly
|
||||
different; see the file gdb-5.1.1/gdb/config/djgpp/README for details.)
|
||||
|
||||
This will configure and build all the libraries as well as GDB. If
|
||||
`configure' can't determine your system type, specify one as its
|
||||
argument, e.g., `./configure sun4' or `./configure decstation'.
|
||||
|
||||
If you get compiler errors during this stage, see the `Reporting
|
||||
Bugs' section below; there are a few known problems.
|
||||
|
||||
GDB requires an ISO C (ANSI C) compiler. If you do not have an ISO
|
||||
C compiler for your system, you may be able to download and install
|
||||
the GNU CC compiler. It is available via anonymous FTP from the
|
||||
directory `ftp://ftp.gnu.org/pub/gnu/gcc'.
|
||||
|
||||
GDB can be used as a cross-debugger, running on a machine of one
|
||||
type while debugging a program running on a machine of another type.
|
||||
See below.
|
||||
|
||||
|
||||
More Documentation
|
||||
******************
|
||||
|
||||
All the documentation for GDB comes as part of the machine-readable
|
||||
distribution. The documentation is written in Texinfo format, which
|
||||
is a documentation system that uses a single source file to produce
|
||||
both on-line information and a printed manual. You can use one of the
|
||||
Info formatting commands to create the on-line version of the
|
||||
documentation and TeX (or `texi2roff') to typeset the printed version.
|
||||
|
||||
GDB includes an already formatted copy of the on-line Info version
|
||||
of this manual in the `gdb/doc' subdirectory. The main Info file is
|
||||
`gdb-5.1.1/gdb/doc/gdb.info', and it refers to subordinate files
|
||||
matching `gdb.info*' in the same directory. If necessary, you can
|
||||
print out these files, or read them with any editor; but they are
|
||||
easier to read using the `info' subsystem in GNU Emacs or the
|
||||
standalone `info' program, available as part of the GNU Texinfo
|
||||
distribution.
|
||||
|
||||
If you want to format these Info files yourself, you need one of the
|
||||
Info formatting programs, such as `texinfo-format-buffer' or
|
||||
`makeinfo'.
|
||||
|
||||
If you have `makeinfo' installed, and are in the top level GDB
|
||||
source directory (`gdb-5.1.1', in the case of version 5.1.1), you can make
|
||||
the Info file by typing:
|
||||
|
||||
cd gdb/doc
|
||||
make info
|
||||
|
||||
If you want to typeset and print copies of this manual, you need
|
||||
TeX, a program to print its DVI output files, and `texinfo.tex', the
|
||||
Texinfo definitions file. This file is included in the GDB
|
||||
distribution, in the directory `gdb-5.1.1/texinfo'.
|
||||
|
||||
TeX is a typesetting program; it does not print files directly, but
|
||||
produces output files called DVI files. To print a typeset document,
|
||||
you need a program to print DVI files. If your system has TeX
|
||||
installed, chances are it has such a program. The precise command to
|
||||
use depends on your system; `lpr -d' is common; another (for PostScript
|
||||
devices) is `dvips'. The DVI print command may require a file name
|
||||
without any extension or a `.dvi' extension.
|
||||
|
||||
TeX also requires a macro definitions file called `texinfo.tex'.
|
||||
This file tells TeX how to typeset a document written in Texinfo
|
||||
format. On its own, TeX cannot read, much less typeset a Texinfo file.
|
||||
`texinfo.tex' is distributed with GDB and is located in the
|
||||
`gdb-5.1.1/texinfo' directory.
|
||||
|
||||
If you have TeX and a DVI printer program installed, you can typeset
|
||||
and print this manual. First switch to the the `gdb' subdirectory of
|
||||
the main source directory (for example, to `gdb-5.1.1/gdb') and then type:
|
||||
|
||||
make doc/gdb.dvi
|
||||
|
||||
If you prefer to have the manual in PDF format, type this from the
|
||||
`gdb/doc' subdirectory of the main source directory:
|
||||
|
||||
make gdb.pdf
|
||||
|
||||
For this to work, you will need the PDFTeX package to be installed.
|
||||
|
||||
|
||||
Installing GDB
|
||||
**************
|
||||
|
||||
GDB comes with a `configure' script that automates the process of
|
||||
preparing GDB for installation; you can then use `make' to build the
|
||||
`gdb' program.
|
||||
|
||||
The GDB distribution includes all the source code you need for GDB in
|
||||
a single directory, whose name is usually composed by appending the
|
||||
version number to `gdb'.
|
||||
|
||||
For example, the GDB version 5.1.1 distribution is in the `gdb-5.1.1'
|
||||
directory. That directory contains:
|
||||
|
||||
`gdb-5.1.1/{COPYING,COPYING.LIB}'
|
||||
Standard GNU license files. Please read them.
|
||||
|
||||
`gdb-5.1.1/bfd'
|
||||
source for the Binary File Descriptor library
|
||||
|
||||
`gdb-5.1.1/config*'
|
||||
script for configuring GDB, along with other support files
|
||||
|
||||
`gdb-5.1.1/gdb'
|
||||
the source specific to GDB itself
|
||||
|
||||
`gdb-5.1.1/include'
|
||||
GNU include files
|
||||
|
||||
`gdb-5.1.1/libiberty'
|
||||
source for the `-liberty' free software library
|
||||
|
||||
`gdb-5.1.1/mmalloc'
|
||||
source for the GNU memory-mapped malloc package
|
||||
|
||||
`gdb-5.1.1/opcodes'
|
||||
source for the library of opcode tables and disassemblers
|
||||
|
||||
`gdb-5.1.1/readline'
|
||||
source for the GNU command-line interface
|
||||
NOTE: The readline library is compiled for use by GDB, but will
|
||||
not be installed on your system when "make install" is issued.
|
||||
|
||||
`gdb-5.1.1/sim'
|
||||
source for some simulators (ARM, D10V, SPARC, M32R, MIPS, PPC, V850, etc)
|
||||
|
||||
`gdb-5.1.1/intl'
|
||||
source for the GNU gettext library, for internationalization.
|
||||
This is slightly modified from the standalone gettext
|
||||
distribution you can get from GNU.
|
||||
|
||||
`gdb-5.1.1/texinfo'
|
||||
The `texinfo.tex' file, which you need in order to make a printed
|
||||
manual using TeX.
|
||||
|
||||
`gdb-5.1.1/etc'
|
||||
Coding standards, useful files for editing GDB, and other
|
||||
miscellanea.
|
||||
|
||||
`gdb-5.1.1/utils'
|
||||
A grab bag of random utilities.
|
||||
|
||||
Note: the following instructions are for building GDB on Unix or
|
||||
Unix-like systems. Instructions for building with DJGPP for
|
||||
MS-DOS/MS-Windows are in the file gdb/config/djgpp/README.
|
||||
|
||||
The simplest way to configure and build GDB is to run `configure'
|
||||
from the `gdb-VERSION-NUMBER' source directory, which in this example
|
||||
is the `gdb-5.1.1' directory.
|
||||
|
||||
First switch to the `gdb-VERSION-NUMBER' source directory if you are
|
||||
not already in it; then run `configure'.
|
||||
|
||||
For example:
|
||||
|
||||
cd gdb-5.1.1
|
||||
./configure
|
||||
make
|
||||
|
||||
Running `configure' followed by `make' builds the `bfd',
|
||||
`readline', `mmalloc', and `libiberty' libraries, then `gdb' itself.
|
||||
The configured source files, and the binaries, are left in the
|
||||
corresponding source directories.
|
||||
|
||||
`configure' is a Bourne-shell (`/bin/sh') script; if your system
|
||||
does not recognize this automatically when you run a different shell,
|
||||
you may need to run `sh' on it explicitly:
|
||||
|
||||
sh configure
|
||||
|
||||
If you run `configure' from a directory that contains source
|
||||
directories for multiple libraries or programs, such as the `gdb-5.1.1'
|
||||
source directory for version 5.1.1, `configure' creates configuration
|
||||
files for every directory level underneath (unless you tell it not to,
|
||||
with the `--norecursion' option).
|
||||
|
||||
You can run the `configure' script from any of the subordinate
|
||||
directories in the GDB distribution, if you only want to configure that
|
||||
subdirectory; but be sure to specify a path to it.
|
||||
|
||||
For example, with version 5.1.1, type the following to configure only
|
||||
the `bfd' subdirectory:
|
||||
|
||||
cd gdb-5.1.1/bfd
|
||||
../configure
|
||||
|
||||
You can install `gdb' anywhere; it has no hardwired paths. However,
|
||||
you should make sure that the shell on your path (named by the `SHELL'
|
||||
environment variable) is publicly readable. Remember that GDB uses the
|
||||
shell to start your program--some systems refuse to let GDB debug child
|
||||
processes whose programs are not readable.
|
||||
|
||||
|
||||
Compiling GDB in another directory
|
||||
==================================
|
||||
|
||||
If you want to run GDB versions for several host or target machines,
|
||||
you need a different `gdb' compiled for each combination of host and
|
||||
target. `configure' is designed to make this easy by allowing you to
|
||||
generate each configuration in a separate subdirectory, rather than in
|
||||
the source directory. If your `make' program handles the `VPATH'
|
||||
feature correctly (GNU `make' and SunOS 'make' are two that should),
|
||||
running `make' in each of these directories builds the `gdb' program
|
||||
specified there.
|
||||
|
||||
To build `gdb' in a separate directory, run `configure' with the
|
||||
`--srcdir' option to specify where to find the source. (You also need
|
||||
to specify a path to find `configure' itself from your working
|
||||
directory. If the path to `configure' would be the same as the
|
||||
argument to `--srcdir', you can leave out the `--srcdir' option; it
|
||||
will be assumed.)
|
||||
|
||||
For example, with version 5.1.1, you can build GDB in a separate
|
||||
directory for a Sun 4 like this:
|
||||
|
||||
cd gdb-5.1.1
|
||||
mkdir ../gdb-sun4
|
||||
cd ../gdb-sun4
|
||||
../gdb-5.1.1/configure
|
||||
make
|
||||
|
||||
When `configure' builds a configuration using a remote source
|
||||
directory, it creates a tree for the binaries with the same structure
|
||||
(and using the same names) as the tree under the source directory. In
|
||||
the example, you'd find the Sun 4 library `libiberty.a' in the
|
||||
directory `gdb-sun4/libiberty', and GDB itself in `gdb-sun4/gdb'.
|
||||
|
||||
One popular reason to build several GDB configurations in separate
|
||||
directories is to configure GDB for cross-compiling (where GDB runs on
|
||||
one machine--the host--while debugging programs that run on another
|
||||
machine--the target). You specify a cross-debugging target by giving
|
||||
the `--target=TARGET' option to `configure'.
|
||||
|
||||
When you run `make' to build a program or library, you must run it
|
||||
in a configured directory--whatever directory you were in when you
|
||||
called `configure' (or one of its subdirectories).
|
||||
|
||||
The `Makefile' that `configure' generates in each source directory
|
||||
also runs recursively. If you type `make' in a source directory such
|
||||
as `gdb-5.1.1' (or in a separate configured directory configured with
|
||||
`--srcdir=PATH/gdb-5.1.1'), you will build all the required libraries,
|
||||
and then build GDB.
|
||||
|
||||
When you have multiple hosts or targets configured in separate
|
||||
directories, you can run `make' on them in parallel (for example, if
|
||||
they are NFS-mounted on each of the hosts); they will not interfere
|
||||
with each other.
|
||||
|
||||
|
||||
Specifying names for hosts and targets
|
||||
======================================
|
||||
|
||||
The specifications used for hosts and targets in the `configure'
|
||||
script are based on a three-part naming scheme, but some short
|
||||
predefined aliases are also supported. The full naming scheme encodes
|
||||
three pieces of information in the following pattern:
|
||||
|
||||
ARCHITECTURE-VENDOR-OS
|
||||
|
||||
For example, you can use the alias `sun4' as a HOST argument or in a
|
||||
`--target=TARGET' option. The equivalent full name is
|
||||
`sparc-sun-sunos4'.
|
||||
|
||||
The `configure' script accompanying GDB does not provide any query
|
||||
facility to list all supported host and target names or aliases.
|
||||
`configure' calls the Bourne shell script `config.sub' to map
|
||||
abbreviations to full names; you can read the script, if you wish, or
|
||||
you can use it to test your guesses on abbreviations--for example:
|
||||
|
||||
% sh config.sub sun4
|
||||
sparc-sun-sunos4.1.1
|
||||
% sh config.sub sun3
|
||||
m68k-sun-sunos4.1.1
|
||||
% sh config.sub decstation
|
||||
mips-dec-ultrix4.2
|
||||
% sh config.sub hp300bsd
|
||||
m68k-hp-bsd
|
||||
% sh config.sub i386v
|
||||
i386-pc-sysv
|
||||
% sh config.sub i786v
|
||||
Invalid configuration `i786v': machine `i786v' not recognized
|
||||
|
||||
`config.sub' is also distributed in the GDB source directory
|
||||
(`gdb-5.1.1', for version 5.1.1).
|
||||
|
||||
|
||||
`configure' options
|
||||
===================
|
||||
|
||||
Here is a summary of the `configure' options and arguments that are
|
||||
most often useful for building GDB. `configure' also has several other
|
||||
options not listed here. *note : (configure.info)What Configure Does,
|
||||
for a full explanation of `configure'.
|
||||
|
||||
configure [--help]
|
||||
[--prefix=DIR]
|
||||
[--srcdir=PATH]
|
||||
[--norecursion] [--rm]
|
||||
[--enable-build-warnings]
|
||||
[--target=TARGET]
|
||||
[--host=HOST]
|
||||
[HOST]
|
||||
|
||||
You may introduce options with a single `-' rather than `--' if you
|
||||
prefer; but you may abbreviate option names if you use `--'.
|
||||
|
||||
`--help'
|
||||
Display a quick summary of how to invoke `configure'.
|
||||
|
||||
`-prefix=DIR'
|
||||
Configure the source to install programs and files under directory
|
||||
`DIR'.
|
||||
|
||||
`--srcdir=PATH'
|
||||
*Warning: using this option requires GNU `make', or another `make'
|
||||
that compatibly implements the `VPATH' feature.*
|
||||
Use this option to make configurations in directories separate
|
||||
from the GDB source directories. Among other things, you can use
|
||||
this to build (or maintain) several configurations simultaneously,
|
||||
in separate directories. `configure' writes configuration
|
||||
specific files in the current directory, but arranges for them to
|
||||
use the source in the directory PATH. `configure' will create
|
||||
directories under the working directory in parallel to the source
|
||||
directories below PATH.
|
||||
|
||||
`--norecursion'
|
||||
Configure only the directory level where `configure' is executed;
|
||||
do not propagate configuration to subdirectories.
|
||||
|
||||
`--rm'
|
||||
Remove the configuration that the other arguments specify.
|
||||
|
||||
`--enable-build-warnings'
|
||||
When building the GDB sources, ask the compiler to warn about any
|
||||
code which looks even vaguely suspicious. You should only using
|
||||
this feature if you're compiling with GNU CC. It passes the
|
||||
following flags:
|
||||
-Wimplicit
|
||||
-Wreturn-type
|
||||
-Wcomment
|
||||
-Wtrigraphs
|
||||
-Wformat
|
||||
-Wparentheses
|
||||
-Wpointer-arith
|
||||
|
||||
`--target=TARGET'
|
||||
Configure GDB for cross-debugging programs running on the specified
|
||||
TARGET. Without this option, GDB is configured to debug programs
|
||||
that run on the same machine (HOST) as GDB itself.
|
||||
|
||||
There is no convenient way to generate a list of all available
|
||||
targets.
|
||||
|
||||
`--host=HOST'
|
||||
Configure GDB to run on the specified HOST.
|
||||
|
||||
There is no convenient way to generate a list of all available
|
||||
hosts.
|
||||
|
||||
`HOST ...'
|
||||
Same as `--host=HOST'. If you omit this, GDB will guess; it's
|
||||
quite accurate.
|
||||
|
||||
`configure' accepts other options, for compatibility with configuring
|
||||
other GNU tools recursively; but these are the only options that affect
|
||||
GDB or its supporting libraries.
|
||||
|
||||
|
||||
Remote debugging
|
||||
=================
|
||||
|
||||
The files m68k-stub.c, i386-stub.c, and sparc-stub.c are examples
|
||||
of remote stubs to be used with remote.c. They are designed to run
|
||||
standalone on an m68k, i386, or SPARC cpu and communicate properly
|
||||
with the remote.c stub over a serial line.
|
||||
|
||||
The directory gdb/gdbserver/ contains `gdbserver', a program that
|
||||
allows remote debugging for Unix applications. gdbserver is only
|
||||
supported for some native configurations, including Sun 3, Sun 4, and
|
||||
Linux.
|
||||
|
||||
There are a number of remote interfaces for talking to existing ROM
|
||||
monitors and other hardware:
|
||||
|
||||
remote-adapt.c AMD 29000 "Adapt"
|
||||
remote-array.c Array Tech RAID controller
|
||||
remote-bug.c Motorola BUG monitor
|
||||
remote-e7000.c Hitachi E7000 ICE
|
||||
remote-eb.c AMD 29000 "EBMON"
|
||||
remote-es.c Ericsson 1800 monitor
|
||||
remote-est.c EST emulator
|
||||
remote-hms.c Hitachi Micro Systems H8/300 monitor
|
||||
remote-mips.c MIPS remote debugging protocol
|
||||
remote-mm.c AMD 29000 "minimon"
|
||||
remote-nindy.c Intel 960 "Nindy"
|
||||
remote-nrom.c NetROM ROM emulator
|
||||
remote-os9k.c PC running OS/9000
|
||||
remote-rdi.c ARM with Angel monitor
|
||||
remote-rdp.c ARM with Demon monitor
|
||||
remote-sds.c PowerPC SDS monitor
|
||||
remote-sim.c Generalized simulator protocol
|
||||
remote-st.c Tandem ST-2000 monitor
|
||||
remote-udi.c AMD 29000 using the AMD "Universal Debug Interface"
|
||||
remote-vx.c VxWorks realtime kernel
|
||||
|
||||
Remote-vx.c and the vx-share subdirectory contain a remote
|
||||
interface for the VxWorks realtime kernel, which communicates over TCP
|
||||
using the Sun RPC library. This would be a useful starting point for
|
||||
other remote- via-ethernet back ends.
|
||||
|
||||
Remote-udi.c and the 29k-share subdirectory contain a remote
|
||||
interface for AMD 29000 programs, which uses the AMD "Universal Debug
|
||||
Interface". This allows GDB to talk to software simulators,
|
||||
emulators, and/or bare hardware boards, via network or serial
|
||||
interfaces. Note that GDB only provides an interface that speaks UDI,
|
||||
not a complete solution. You will need something on the other end
|
||||
that also speaks UDI.
|
||||
|
||||
|
||||
Reporting Bugs
|
||||
===============
|
||||
|
||||
The correct address for reporting bugs found in gdb is
|
||||
"bug-gdb@gnu.org". Please email all bugs, and all requests for help
|
||||
with GDB, to that address. Please include the GDB version number
|
||||
(e.g., gdb-5.1.1), and how you configured it (e.g., "sun4" or "mach386
|
||||
host, i586-intel-synopsys target"). Since GDB now supports so many
|
||||
different configurations, it is important that you be precise about
|
||||
this. If at all possible, you should include the actual banner that
|
||||
GDB prints when it starts up, or failing that, the actual configure
|
||||
command that you used when configuring GDB.
|
||||
|
||||
For more information on how/whether to report bugs, see the GDB
|
||||
Bugs section of the GDB manual (gdb/doc/gdb.texinfo) or the
|
||||
gdb/CONTRIBUTE file.
|
||||
|
||||
|
||||
Graphical interface to GDB -- X Windows, MS Windows
|
||||
==========================
|
||||
|
||||
Several graphical interfaces to GDB are available. You should
|
||||
check:
|
||||
|
||||
http://sourceware.cygnus.com/gdb/#gui
|
||||
|
||||
for an up-to-date list.
|
||||
|
||||
Emacs users will very likely enjoy the Grand Unified Debugger mode;
|
||||
try typing `M-x gdb RET'.
|
||||
|
||||
|
||||
Writing Code for GDB
|
||||
=====================
|
||||
|
||||
There is a lot of information about writing code for GDB in the
|
||||
internals manual, distributed with GDB in gdb/doc/gdbint.texinfo. You
|
||||
can read it by hand, print it by using TeX and texinfo, or process it
|
||||
into an `info' file for use with Emacs' info mode or the standalone
|
||||
`info' program.
|
||||
|
||||
If you are pondering writing anything but a short patch, especially
|
||||
take note of the information about copyrights in the node Submitting
|
||||
Patches. It can take quite a while to get all the paperwork done, so
|
||||
we encourage you to start that process as soon as you decide you are
|
||||
planning to work on something, or at least well ahead of when you
|
||||
think you will be ready to submit the patches.
|
||||
|
||||
|
||||
GDB Testsuite
|
||||
=============
|
||||
|
||||
Included with the GDB distribution is a DejaGNU based testsuite
|
||||
that can either be used to test your newly built GDB, or for
|
||||
regression testing a GDB with local modifications.
|
||||
|
||||
Running the testsuite requires the prior installation of DejaGNU,
|
||||
which is generally available via ftp. The directory
|
||||
ftp://sourceware.cygnus.com/pub/dejagnu/ will contain a recent
|
||||
snapshot. Once DejaGNU is installed, you can run the tests in one of
|
||||
the following ways:
|
||||
|
||||
(1) cd gdb-5.1.1
|
||||
make check-gdb
|
||||
|
||||
or
|
||||
|
||||
(2) cd gdb-5.1.1/gdb
|
||||
make check
|
||||
|
||||
or
|
||||
|
||||
(3) cd gdb-5.1.1/gdb/testsuite
|
||||
make site.exp (builds the site specific file)
|
||||
runtest -tool gdb GDB=../gdb (or GDB=<somepath> as appropriate)
|
||||
|
||||
The last method gives you slightly more control in case of problems
|
||||
with building one or more test executables or if you are using the
|
||||
testsuite `standalone', without it being part of the GDB source tree.
|
||||
|
||||
See the DejaGNU documentation for further details.
|
||||
|
||||
|
||||
(this is for editing this file with GNU emacs)
|
||||
Local Variables:
|
||||
mode: text
|
||||
End:
|
||||
351
gdb/TODO
351
gdb/TODO
@@ -1,351 +0,0 @@
|
||||
If you find inaccuracies in this list, please send mail to
|
||||
gdb-patches@sources.redhat.com. If you would like to work on any
|
||||
of these, you should consider sending mail to the same address, to
|
||||
find out whether anyone else is working on it.
|
||||
|
||||
|
||||
GDB 5.1 - Fixes
|
||||
===============
|
||||
|
||||
Below is a list of problems identified during the GDB 5.0 release
|
||||
cycle. People hope to have these problems fixed in 5.1.
|
||||
|
||||
--
|
||||
|
||||
Wow, three bug reports for the same problem in one day! We should
|
||||
probably make fixing this a real priority :-).
|
||||
|
||||
Anyway, thanks for reporting.
|
||||
|
||||
The following patch will fix the problems with setting breakpoints in
|
||||
dynamically loaded objects:
|
||||
|
||||
http://sources.redhat.com/ml/gdb-patches/2000-05/msg00230.html
|
||||
|
||||
This patch isn't checked in yet (ping Michael/JimB), but I hope this
|
||||
will be in the next GDB release.
|
||||
|
||||
There should really be a test in the testsuite for this problem, since
|
||||
it keeps coming up :-(. Any volunteers?
|
||||
|
||||
Mark
|
||||
|
||||
--
|
||||
|
||||
GDB 5.1 - New features
|
||||
======================
|
||||
|
||||
The following new features should be included in 5.1.
|
||||
|
||||
--
|
||||
|
||||
GDB 5.1 - Cleanups
|
||||
==================
|
||||
|
||||
The following code cleanups will hopefully be applied to GDB 5.1.
|
||||
|
||||
--
|
||||
|
||||
GDB 5.1 - Known Problems
|
||||
========================
|
||||
|
||||
--
|
||||
|
||||
z8k
|
||||
|
||||
The z8k has suffered bit rot and is known to not build. The problem
|
||||
was occuring in the opcodes directory.
|
||||
|
||||
--
|
||||
|
||||
The BFD directory requires bug-fixed AUTOMAKE et.al.
|
||||
|
||||
AUTOMAKE 1.4 incorrectly set the TEXINPUTS environment variable. It
|
||||
contained the full path to texinfo.tex when it should have only
|
||||
contained the directory. The bug has been fixed in the current
|
||||
AUTOMAKE sources. Automake snapshots can be found in:
|
||||
ftp://sources.redhat.com/pub/gdb/infrastructure
|
||||
and ftp://sources.redhat.com/pub/binutils
|
||||
|
||||
--
|
||||
|
||||
Solaris 8 x86 CURSES_H problem
|
||||
http://sources.redhat.com/ml/gdb/2000-07/msg00038.html
|
||||
|
||||
The original problem was worked around with:
|
||||
|
||||
2000-06-06 Michael Snyder <msnyder@cygnus.com>
|
||||
|
||||
* configure.in: Enable autoconf to find curses.h on Solaris 2.8.
|
||||
* configure: Regenerate.
|
||||
|
||||
When building both GDB and SID using the same source tree the problem
|
||||
will still occure. sid/component/configure.in mis-configures
|
||||
<curses.h> and leaves wrong information in the config cache.
|
||||
|
||||
--
|
||||
|
||||
GDB 5.2 - Fixes
|
||||
===============
|
||||
|
||||
--
|
||||
|
||||
GDB 5.2 - New features
|
||||
======================
|
||||
|
||||
--
|
||||
|
||||
GCC 3.0 ABI support (but hopefully sooner...).
|
||||
|
||||
--
|
||||
|
||||
Objective C/C++ support (but hopefully sooner...).
|
||||
|
||||
--
|
||||
|
||||
Import of readline 4.2
|
||||
|
||||
--
|
||||
|
||||
GDB 5.2 - Cleanups
|
||||
==================
|
||||
|
||||
The following cleanups have been identified as part of GDB 5.2.
|
||||
|
||||
--
|
||||
|
||||
Remove old code that does not use ui_out functions and all the related
|
||||
"ifdef"s. This also allows the elimination of -DUI_OUT from
|
||||
Makefile.in and configure.in.
|
||||
|
||||
--
|
||||
|
||||
Compiler warnings.
|
||||
|
||||
Eliminate warnings for all targets on at least one host for one of the
|
||||
-W flags. Flags up for debate include: -Wswitch -Wcomment -trigraphs
|
||||
-Wtrigraphs -Wunused-function -Wunused-label -Wunused-variable
|
||||
-Wunused-value -Wchar-subscripts -Wtraditional -Wshadow -Wcast-qual
|
||||
-Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes
|
||||
-Wmissing-prototypes -Wmissing-declarations -Wredundant-decls
|
||||
-Woverloaded-virtual -Winline
|
||||
|
||||
--
|
||||
|
||||
Deprecate, if not delete, the following:
|
||||
|
||||
register[]
|
||||
register_valid[]
|
||||
REGISTER_BYTE()
|
||||
Replaced by, on the target side
|
||||
supply_register()
|
||||
and on core-gdb side:
|
||||
{read,write}_register_gen()
|
||||
Remote.c will need to use something
|
||||
other than REGISTER_BYTE() and
|
||||
REGISTER_RAW_SIZE() when unpacking
|
||||
[gG] packets.
|
||||
|
||||
STORE_PSEUDO_REGISTER
|
||||
FETCH_PSEUDO_REGISTER
|
||||
Now handed by the methods
|
||||
gdbarch_{read,write}_register()
|
||||
which sits between core GDB and
|
||||
the register cache.
|
||||
|
||||
REGISTER_CONVERTIBLE
|
||||
REGISTER_CONVERT_TO_RAW
|
||||
REGISTER_CONVERT_TO_VIRTUAL
|
||||
I think these three are redundant.
|
||||
gdbarch_register_{read,write} can
|
||||
do any conversion it likes.
|
||||
|
||||
REGISTER_VIRTUAL_SIZE
|
||||
MAX_REGISTER_VIRTUAL_SIZE
|
||||
REGISTER_VIRTUAL_TYPE
|
||||
I think these can be replaced by
|
||||
the pair:
|
||||
FRAME_REGISTER_TYPE(frame, regnum)
|
||||
REGISTER_TYPE(regnum)
|
||||
|
||||
DO_REGISTERS_INFO
|
||||
Replace with
|
||||
FRAME_REGISTER_INFO (frame, ...)
|
||||
|
||||
REGISTER_SIM_REGNO()
|
||||
If nothing else rename this so that
|
||||
how it relates to rawreg and the
|
||||
regnum is clear.
|
||||
|
||||
REGISTER_BYTES
|
||||
The size of the cache can be computed
|
||||
on the fly.
|
||||
|
||||
IS_TRAPPED_INTERNALVAR
|
||||
The pseudo registers should eventually make
|
||||
this redundant.
|
||||
|
||||
--
|
||||
|
||||
Obsolete the targets:
|
||||
|
||||
arm*-wince-pe
|
||||
mips*-*-pe
|
||||
sh*-*-pe
|
||||
|
||||
--
|
||||
|
||||
Obsolete the protocols:
|
||||
|
||||
RDB?
|
||||
|
||||
``As of version 5.3, WindRiver has removed the RDB server (RDB
|
||||
protocol support is built into gdb).'' -- Till.
|
||||
|
||||
--
|
||||
|
||||
Restructure gdb directory tree so that it avoids any 8.3 and 14
|
||||
filename problems.
|
||||
|
||||
--
|
||||
|
||||
Convert GDB build process to AUTOMAKE.
|
||||
|
||||
See also sub-directory configure below.
|
||||
|
||||
The current convention is (kind of) to use $(<header>_h) in all
|
||||
dependency lists. It isn't done in a consistent way.
|
||||
|
||||
--
|
||||
|
||||
GDB 5.2 - Known Problems
|
||||
========================
|
||||
|
||||
--
|
||||
|
||||
Code Cleanups: General
|
||||
======================
|
||||
|
||||
The following are more general cleanups and fixes. They are not tied
|
||||
to any specific release.
|
||||
|
||||
|
||||
New Features and Fixes
|
||||
======================
|
||||
|
||||
These are harder than cleanups but easier than work involving
|
||||
fundamental architectural change.
|
||||
|
||||
--
|
||||
|
||||
Language Support
|
||||
================
|
||||
|
||||
New languages come onto the scene all the time.
|
||||
|
||||
--
|
||||
|
||||
Re: Various C++ things
|
||||
|
||||
value_headof/value_from_vtable_info are worthless, and should be
|
||||
removed. The one place in printcmd.c that uses it should use the RTTI
|
||||
functions.
|
||||
|
||||
RTTI for g++ should be using the typeinfo functions rather than the
|
||||
vtables. The typeinfo functions are always at offset 4 from the
|
||||
beginning of the vtable, and are always right. The vtables will have
|
||||
weird names like E::VB sometimes. The typeinfo function will always
|
||||
be "E type_info function", or somesuch.
|
||||
|
||||
value_virtual_fn_field needs to be fixed so there are no failures for
|
||||
virtual functions for C++ using g++.
|
||||
|
||||
Testsuite cases are the major priority right now for C++ support,
|
||||
since i have to make a lot of changes that could potentially break
|
||||
each other.
|
||||
|
||||
--
|
||||
|
||||
|
||||
Symbol Support
|
||||
==============
|
||||
|
||||
--
|
||||
|
||||
Investiagate ways of reducing memory.
|
||||
|
||||
--
|
||||
|
||||
Investigate ways of improving load time.
|
||||
|
||||
--
|
||||
|
||||
Testsuite Support
|
||||
=================
|
||||
|
||||
There are never to many testcases.
|
||||
|
||||
--
|
||||
|
||||
Better thread testsuite.
|
||||
|
||||
--
|
||||
|
||||
Better C++ testsuite.
|
||||
|
||||
--
|
||||
|
||||
Architectural Changes: General
|
||||
==============================
|
||||
|
||||
These are harder than simple cleanups / fixes and, consequently
|
||||
involve more work. Typically an Architectural Change will be broken
|
||||
down into a more digestible set of cleanups and fixes.
|
||||
|
||||
--
|
||||
|
||||
Architectural Change: Multi-arch et al.
|
||||
=======================================
|
||||
|
||||
The long term objective is to remove all assumptions that there is a
|
||||
single target with a single address space with a single instruction
|
||||
set architecture and single application binary interface.
|
||||
|
||||
This is an ongoing effort. The first milestone is to enable
|
||||
``multi-arch'' where by all architectural decisions are made at
|
||||
runtime.
|
||||
|
||||
It should be noted that ``gdbarch'' is really ``gdbabi'' and
|
||||
``gdbisa''. Once things are multi-arched breaking that down correctly
|
||||
will become much easier.
|
||||
|
||||
--
|
||||
|
||||
Architectural Change: MI, LIBGDB and scripting languages
|
||||
========================================================
|
||||
|
||||
See also architectural changes related to the event loop. LIBGDB
|
||||
can't be finished until there is a generic event loop being used by
|
||||
all targets.
|
||||
|
||||
The long term objective is it to be possible to integrate GDB into
|
||||
scripting languages.
|
||||
|
||||
--
|
||||
|
||||
Architectural Change: Async
|
||||
===========================
|
||||
|
||||
While GDB uses an event loop when prompting the user for input. That
|
||||
event loop is not exploited by targets when they allow the target
|
||||
program to continue. Typically targets still block in (target_wait())
|
||||
until the program again halts.
|
||||
|
||||
The closest a target comes to supporting full asynchronous mode are
|
||||
the remote targets ``async'' and ``extended-async''.
|
||||
|
||||
--
|
||||
|
||||
# Local Variables:
|
||||
# mode: text
|
||||
# End:
|
||||
1015
gdb/a29k-tdep.c
1015
gdb/a29k-tdep.c
File diff suppressed because it is too large
Load Diff
122
gdb/a68v-nat.c
122
gdb/a68v-nat.c
@@ -1,122 +0,0 @@
|
||||
/* Host-dependent code for Apollo-68ks for GDB, the GNU debugger.
|
||||
Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
#include "regcache.h"
|
||||
|
||||
#ifndef _ISP__M68K
|
||||
#define _ISP__M68K 1
|
||||
#endif
|
||||
|
||||
#include <ptrace.h>
|
||||
|
||||
extern int errno;
|
||||
|
||||
void
|
||||
fetch_inferior_registers (int ignored)
|
||||
{
|
||||
struct ptrace_$data_regs_m68k inferior_registers;
|
||||
struct ptrace_$floating_regs_m68k inferior_fp_registers;
|
||||
struct ptrace_$control_regs_m68k inferior_control_registers;
|
||||
|
||||
ptrace_$init_control (&inferior_control_registers);
|
||||
inferior_fp_registers.size = sizeof (inferior_fp_registers);
|
||||
|
||||
registers_fetched ();
|
||||
|
||||
ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) & inferior_registers,
|
||||
ptrace_$data_set,
|
||||
(PTRACE_ARG3_TYPE) & inferior_registers,
|
||||
ptrace_$data_set);
|
||||
|
||||
ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) & inferior_fp_registers,
|
||||
ptrace_$floating_set_m68k,
|
||||
(PTRACE_ARG3_TYPE) & inferior_fp_registers,
|
||||
ptrace_$floating_set_m68k);
|
||||
|
||||
ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) & inferior_control_registers,
|
||||
ptrace_$control_set_m68k,
|
||||
(PTRACE_ARG3_TYPE) & inferior_control_registers,
|
||||
ptrace_$control_set_m68k);
|
||||
|
||||
bcopy (&inferior_registers, registers, 16 * 4);
|
||||
bcopy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)],
|
||||
sizeof inferior_fp_registers.regs);
|
||||
*(int *) ®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_control_registers.sr;
|
||||
*(int *) ®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_control_registers.pc;
|
||||
}
|
||||
|
||||
/* Store our register values back into the inferior.
|
||||
If REGNO is -1, do this for all registers.
|
||||
Otherwise, REGNO specifies which register (so we can save time). */
|
||||
|
||||
void
|
||||
store_inferior_registers (int regno)
|
||||
{
|
||||
struct ptrace_$data_regs_m68k inferior_registers;
|
||||
struct ptrace_$floating_regs_m68k inferior_fp_registers;
|
||||
struct ptrace_$control_regs_m68k inferior_control_registers;
|
||||
|
||||
ptrace_$init_control (&inferior_control_registers);
|
||||
inferior_fp_registers.size = sizeof (inferior_fp_registers);
|
||||
|
||||
ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) & inferior_fp_registers,
|
||||
ptrace_$floating_set_m68k,
|
||||
(PTRACE_ARG3_TYPE) & inferior_fp_registers,
|
||||
ptrace_$floating_set_m68k);
|
||||
|
||||
ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) & inferior_control_registers,
|
||||
ptrace_$control_set_m68k,
|
||||
(PTRACE_ARG3_TYPE) & inferior_control_registers,
|
||||
ptrace_$control_set_m68k);
|
||||
|
||||
bcopy (registers, &inferior_registers, sizeof (inferior_registers));
|
||||
|
||||
bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], inferior_fp_registers.regs,
|
||||
sizeof inferior_fp_registers.regs);
|
||||
|
||||
inferior_control_registers.sr = *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)];
|
||||
inferior_control_registers.pc = *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)];
|
||||
|
||||
ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) & inferior_registers,
|
||||
ptrace_$data_set_m68k,
|
||||
(PTRACE_ARG3_TYPE) & inferior_registers,
|
||||
ptrace_$data_set_m68k);
|
||||
|
||||
ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) & inferior_fp_registers,
|
||||
ptrace_$floating_set_m68k,
|
||||
(PTRACE_ARG3_TYPE) & inferior_fp_registers,
|
||||
ptrace_$floating_set_m68k);
|
||||
|
||||
ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) & inferior_control_registers,
|
||||
ptrace_$control_set_m68k,
|
||||
(PTRACE_ARG3_TYPE) & inferior_control_registers,
|
||||
ptrace_$control_set_m68k);
|
||||
}
|
||||
167
gdb/abug-rom.c
167
gdb/abug-rom.c
@@ -1,167 +0,0 @@
|
||||
/* Remote debugging interface for ABug Rom monitor for GDB, the GNU debugger.
|
||||
Copyright 1995, 1996, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Written by Rob Savoye of Cygnus Support
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "monitor.h"
|
||||
#include "serial.h"
|
||||
#include "regcache.h"
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
|
||||
static void abug_open (char *args, int from_tty);
|
||||
|
||||
static void
|
||||
abug_supply_register (char *regname, int regnamelen, char *val, int vallen)
|
||||
{
|
||||
int regno;
|
||||
|
||||
if (regnamelen != 2)
|
||||
return;
|
||||
|
||||
switch (regname[0])
|
||||
{
|
||||
case 'S':
|
||||
if (regname[1] != 'R')
|
||||
return;
|
||||
regno = PS_REGNUM;
|
||||
break;
|
||||
case 'P':
|
||||
if (regname[1] != 'C')
|
||||
return;
|
||||
regno = PC_REGNUM;
|
||||
break;
|
||||
case 'D':
|
||||
if (regname[1] < '0' || regname[1] > '7')
|
||||
return;
|
||||
regno = regname[1] - '0' + D0_REGNUM;
|
||||
break;
|
||||
case 'A':
|
||||
if (regname[1] < '0' || regname[1] > '7')
|
||||
return;
|
||||
regno = regname[1] - '0' + A0_REGNUM;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
monitor_supply_register (regno, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* This array of registers needs to match the indexes used by GDB. The
|
||||
* whole reason this exists is because the various ROM monitors use
|
||||
* different names than GDB does, and don't support all the
|
||||
* registers either. So, typing "info reg sp" becomes an "A7".
|
||||
*/
|
||||
|
||||
static char *abug_regnames[NUM_REGS] =
|
||||
{
|
||||
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
|
||||
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
|
||||
"PC",
|
||||
};
|
||||
|
||||
/*
|
||||
* Define the monitor command strings. Since these are passed directly
|
||||
* through to a printf style function, we need can include formatting
|
||||
* strings. We also need a CR or LF on the end.
|
||||
*/
|
||||
|
||||
static struct target_ops abug_ops;
|
||||
|
||||
static char *abug_inits[] =
|
||||
{"\r", NULL};
|
||||
|
||||
static struct monitor_ops abug_cmds;
|
||||
|
||||
static void
|
||||
init_abug_cmds (void)
|
||||
{
|
||||
abug_cmds.flags = MO_CLR_BREAK_USES_ADDR;
|
||||
abug_cmds.init = abug_inits; /* Init strings */
|
||||
abug_cmds.cont = "g\r"; /* continue command */
|
||||
abug_cmds.step = "t\r"; /* single step */
|
||||
abug_cmds.stop = NULL; /* interrupt command */
|
||||
abug_cmds.set_break = "br %x\r"; /* set a breakpoint */
|
||||
abug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */
|
||||
abug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */
|
||||
abug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */
|
||||
abug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */
|
||||
abug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */
|
||||
abug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */
|
||||
abug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
|
||||
abug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
|
||||
abug_cmds.setmem.term = NULL; /* setreg.term */
|
||||
abug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
|
||||
abug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */
|
||||
abug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */
|
||||
abug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */
|
||||
abug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
|
||||
abug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */
|
||||
abug_cmds.getmem.term = NULL; /* getmem.term */
|
||||
abug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
|
||||
abug_cmds.setreg.cmd = "rm %s %x\r"; /* setreg.cmd (name, value) */
|
||||
abug_cmds.setreg.resp_delim = "="; /* setreg.resp_delim */
|
||||
abug_cmds.setreg.term = "? "; /* setreg.term */
|
||||
abug_cmds.setreg.term_cmd = ".\r"; /* setreg.term_cmd */
|
||||
abug_cmds.getreg.cmd = "rm %s\r"; /* getreg.cmd (name) */
|
||||
abug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
|
||||
abug_cmds.getreg.term = "? "; /* getreg.term */
|
||||
abug_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */
|
||||
abug_cmds.dump_registers = "rd\r"; /* dump_registers */
|
||||
abug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
|
||||
abug_cmds.supply_register = abug_supply_register; /* supply_register */
|
||||
abug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
|
||||
abug_cmds.load = "lo 0\r"; /* download command */
|
||||
abug_cmds.loadresp = "\n"; /* load response */
|
||||
abug_cmds.prompt = "135Bug>"; /* monitor command prompt */
|
||||
abug_cmds.line_term = "\r"; /* end-of-line terminator */
|
||||
abug_cmds.cmd_end = NULL; /* optional command terminator */
|
||||
abug_cmds.target = &abug_ops; /* target operations */
|
||||
abug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
|
||||
abug_cmds.regnames = abug_regnames; /* registers names */
|
||||
abug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
|
||||
};
|
||||
|
||||
static void
|
||||
abug_open (char *args, int from_tty)
|
||||
{
|
||||
monitor_open (args, &abug_cmds, from_tty);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_abug_rom (void)
|
||||
{
|
||||
init_abug_cmds ();
|
||||
init_monitor_ops (&abug_ops);
|
||||
|
||||
abug_ops.to_shortname = "abug";
|
||||
abug_ops.to_longname = "ABug monitor";
|
||||
abug_ops.to_doc = "Debug via the ABug monitor.\n\
|
||||
Specify the serial device it is connected to (e.g. /dev/ttya).";
|
||||
abug_ops.to_open = abug_open;
|
||||
|
||||
add_target (&abug_ops);
|
||||
}
|
||||
175
gdb/acconfig.h
175
gdb/acconfig.h
@@ -1,175 +0,0 @@
|
||||
/* Define if compiling on Solaris 7. */
|
||||
#undef _MSE_INT_H
|
||||
|
||||
/* Define if your struct reg has r_fs. */
|
||||
#undef HAVE_STRUCT_REG_R_FS
|
||||
|
||||
/* Define if your struct reg has r_gs. */
|
||||
#undef HAVE_STRUCT_REG_R_GS
|
||||
|
||||
/* Define if pstatus_t type is available */
|
||||
#undef HAVE_PSTATUS_T
|
||||
|
||||
/* Define if prrun_t type is available */
|
||||
#undef HAVE_PRRUN_T
|
||||
|
||||
/* Define if fpregset_t type is available. */
|
||||
#undef HAVE_FPREGSET_T
|
||||
|
||||
/* Define if gregset_t type is available. */
|
||||
#undef HAVE_GREGSET_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prgregset_t. */
|
||||
#undef HAVE_PRGREGSET_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prfpregset_t. */
|
||||
#undef HAVE_PRFPREGSET_T
|
||||
|
||||
/* Define if <sys/procfs.h> has lwpid_t. */
|
||||
#undef HAVE_LWPID_T
|
||||
|
||||
/* Define if <sys/procfs.h> has psaddr_t. */
|
||||
#undef HAVE_PSADDR_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prgregset32_t. */
|
||||
#undef HAVE_PRGREGSET32_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prfpregset32_t. */
|
||||
#undef HAVE_PRFPREGSET32_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prsysent_t */
|
||||
#undef HAVE_PRSYSENT_T
|
||||
|
||||
/* Define if <sys/procfs.h> has pr_sigset_t */
|
||||
#undef HAVE_PR_SIGSET_T
|
||||
|
||||
/* Define if <sys/procfs.h> has pr_sigaction64_t */
|
||||
#undef HAVE_PR_SIGACTION64_T
|
||||
|
||||
/* Define if <sys/procfs.h> has pr_siginfo64_t */
|
||||
#undef HAVE_PR_SIGINFO64_T
|
||||
|
||||
/* Define if <link.h> exists and defines struct link_map which has
|
||||
members with an ``l_'' prefix. (For Solaris, SVR4, and
|
||||
SVR4-like systems.) */
|
||||
#undef HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS
|
||||
|
||||
/* Define if <link.h> exists and defines struct link_map which has
|
||||
members with an ``lm_'' prefix. (For SunOS.) */
|
||||
#undef HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS
|
||||
|
||||
/* Define if <link.h> exists and defines a struct so_map which has
|
||||
members with an ``som_'' prefix. (Found on older *BSD systems.) */
|
||||
#undef HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS
|
||||
|
||||
/* Define if <sys/link.h> has struct link_map32 */
|
||||
#undef HAVE_STRUCT_LINK_MAP32
|
||||
|
||||
/* Define if the prfpregset_t type is broken. */
|
||||
#undef PRFPREGSET_T_BROKEN
|
||||
|
||||
/* Define if you want to use new multi-fd /proc interface
|
||||
(replaces HAVE_MULTIPLE_PROC_FDS as well as other macros). */
|
||||
#undef NEW_PROC_API
|
||||
|
||||
/* Define if ioctl argument PIOCSET is available. */
|
||||
#undef HAVE_PROCFS_PIOCSET
|
||||
|
||||
/* Define if the `long long' type works. */
|
||||
#undef CC_HAS_LONG_LONG
|
||||
|
||||
/* Define if the "ll" format works to print long long ints. */
|
||||
#undef PRINTF_HAS_LONG_LONG
|
||||
|
||||
/* Define if the "%Lg" format works to print long doubles. */
|
||||
#undef PRINTF_HAS_LONG_DOUBLE
|
||||
|
||||
/* Define if the "%Lg" format works to scan long doubles. */
|
||||
#undef SCANF_HAS_LONG_DOUBLE
|
||||
|
||||
/* Define if using Solaris thread debugging. */
|
||||
#undef HAVE_THREAD_DB_LIB
|
||||
|
||||
/* Define on a GNU/Linux system to work around problems in sys/procfs.h. */
|
||||
#undef START_INFERIOR_TRAPS_EXPECTED
|
||||
#undef sys_quotactl
|
||||
|
||||
/* Define if you have HPUX threads */
|
||||
#undef HAVE_HPUX_THREAD_SUPPORT
|
||||
|
||||
/* Define if you want to use the memory mapped malloc package (mmalloc). */
|
||||
#undef USE_MMALLOC
|
||||
|
||||
/* Define if the runtime uses a routine from mmalloc before gdb has a chance
|
||||
to initialize mmalloc, and we want to force checking to be used anyway.
|
||||
This may cause spurious memory corruption messages if the runtime tries
|
||||
to explicitly deallocate that memory when gdb calls exit. */
|
||||
#undef MMCHECK_FORCE
|
||||
|
||||
/* Define to 1 if NLS is requested. */
|
||||
#undef ENABLE_NLS
|
||||
|
||||
/* Define as 1 if you have catgets and don't want to use GNU gettext. */
|
||||
#undef HAVE_CATGETS
|
||||
|
||||
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
|
||||
#undef HAVE_GETTEXT
|
||||
|
||||
/* Define as 1 if you have the stpcpy function. */
|
||||
#undef HAVE_STPCPY
|
||||
|
||||
/* Define if your locale.h file contains LC_MESSAGES. */
|
||||
#undef HAVE_LC_MESSAGES
|
||||
|
||||
/* Define if you want to use the full-screen terminal user interface. */
|
||||
#undef TUI
|
||||
|
||||
/* Define if <proc_service.h> on solaris uses int instead of
|
||||
size_t, and assorted other type changes. */
|
||||
#undef PROC_SERVICE_IS_OLD
|
||||
|
||||
/* If you want to specify a default CPU variant, define this to be its
|
||||
name, as a C string. */
|
||||
#undef TARGET_CPU_DEFAULT
|
||||
|
||||
/* Define if the simulator is being linked in. */
|
||||
#undef WITH_SIM
|
||||
|
||||
/* Set to true if the save_state_t structure is present */
|
||||
#undef HAVE_STRUCT_SAVE_STATE_T
|
||||
|
||||
/* Set to true if the save_state_t structure has the ss_wide member */
|
||||
#undef HAVE_STRUCT_MEMBER_SS_WIDE
|
||||
|
||||
/* Define if <sys/ptrace.h> defines the PTRACE_GETREGS request. */
|
||||
#undef HAVE_PTRACE_GETREGS
|
||||
|
||||
/* Define if <sys/ptrace.h> defines the PTRACE_GETFPXREGS request. */
|
||||
#undef HAVE_PTRACE_GETFPXREGS
|
||||
|
||||
/* Define if <sys/ptrace.h> defines the PT_GETDBREGS request. */
|
||||
#undef HAVE_PT_GETDBREGS
|
||||
|
||||
/* Define if <sys/ptrace.h> defines the PT_GETXMMREGS request. */
|
||||
#undef HAVE_PT_GETXMMREGS
|
||||
|
||||
/* Define if gnu-regex.c included with GDB should be used. */
|
||||
#undef USE_INCLUDED_REGEX
|
||||
|
||||
/* BFD's default architecture. */
|
||||
#undef DEFAULT_BFD_ARCH
|
||||
|
||||
/* BFD's default target vector. */
|
||||
#undef DEFAULT_BFD_VEC
|
||||
|
||||
/* Multi-arch enabled. */
|
||||
#undef GDB_MULTI_ARCH
|
||||
|
||||
/* hostfile */
|
||||
#undef GDB_XM_FILE
|
||||
|
||||
/* targetfile */
|
||||
#undef GDB_TM_FILE
|
||||
|
||||
/* nativefile */
|
||||
#undef GDB_NM_FILE
|
||||
868
gdb/acinclude.m4
868
gdb/acinclude.m4
@@ -1,868 +0,0 @@
|
||||
dnl written by Rob Savoye <rob@cygnus.com> for Cygnus Support
|
||||
dnl major rewriting for Tcl 7.5 by Don Libes <libes@nist.gov>
|
||||
|
||||
dnl gdb/configure.in uses BFD_NEED_DECLARATION, so get its definition.
|
||||
sinclude(../bfd/acinclude.m4)
|
||||
|
||||
dnl This gets the standard macros, like the TCL, TK, etc ones.
|
||||
sinclude(../config/acinclude.m4)
|
||||
|
||||
dnl CYGNUS LOCAL: This gets the right posix flag for gcc
|
||||
AC_DEFUN(CY_AC_TCL_LYNX_POSIX,
|
||||
[AC_REQUIRE([AC_PROG_CC])AC_REQUIRE([AC_PROG_CPP])
|
||||
AC_MSG_CHECKING([if running LynxOS])
|
||||
AC_CACHE_VAL(ac_cv_os_lynx,
|
||||
[AC_EGREP_CPP(yes,
|
||||
[/*
|
||||
* The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__"
|
||||
*/
|
||||
#if defined(__Lynx__) || defined(Lynx)
|
||||
yes
|
||||
#endif
|
||||
], ac_cv_os_lynx=yes, ac_cv_os_lynx=no)])
|
||||
#
|
||||
if test "$ac_cv_os_lynx" = "yes" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(LYNX)
|
||||
AC_MSG_CHECKING([whether -mposix or -X is available])
|
||||
AC_CACHE_VAL(ac_cv_c_posix_flag,
|
||||
[AC_TRY_COMPILE(,[
|
||||
/*
|
||||
* This flag varies depending on how old the compiler is.
|
||||
* -X is for the old "cc" and "gcc" (based on 1.42).
|
||||
* -mposix is for the new gcc (at least 2.5.8).
|
||||
*/
|
||||
#if defined(__GNUC__) && __GNUC__ >= 2
|
||||
choke me
|
||||
#endif
|
||||
], ac_cv_c_posix_flag=" -mposix", ac_cv_c_posix_flag=" -X")])
|
||||
CC="$CC $ac_cv_c_posix_flag"
|
||||
AC_MSG_RESULT($ac_cv_c_posix_flag)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
])
|
||||
|
||||
#
|
||||
# Sometimes the native compiler is a bogus stub for gcc or /usr/ucb/cc. This
|
||||
# makes configure think it's cross compiling. If --target wasn't used, then
|
||||
# we can't configure, so something is wrong. We don't use the cache
|
||||
# here cause if somebody fixes their compiler install, we want this to work.
|
||||
AC_DEFUN(CY_AC_C_WORKS,
|
||||
[# If we cannot compile and link a trivial program, we can't expect anything to work
|
||||
AC_MSG_CHECKING(whether the compiler ($CC) actually works)
|
||||
AC_TRY_COMPILE(, [/* don't need anything here */],
|
||||
c_compiles=yes, c_compiles=no)
|
||||
|
||||
AC_TRY_LINK(, [/* don't need anything here */],
|
||||
c_links=yes, c_links=no)
|
||||
|
||||
if test x"${c_compiles}" = x"no" ; then
|
||||
AC_MSG_ERROR(the native compiler is broken and won't compile.)
|
||||
fi
|
||||
|
||||
if test x"${c_links}" = x"no" ; then
|
||||
AC_MSG_ERROR(the native compiler is broken and won't link.)
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
])
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_TCLH, [
|
||||
#
|
||||
# Ok, lets find the tcl source trees so we can use the headers
|
||||
# Warning: transition of version 9 to 10 will break this algorithm
|
||||
# because 10 sorts before 9. We also look for just tcl. We have to
|
||||
# be careful that we don't match stuff like tclX by accident.
|
||||
# the alternative search directory is involked by --with-tclinclude
|
||||
#
|
||||
|
||||
no_tcl=true
|
||||
AC_MSG_CHECKING(for Tcl private headers. dir=${configdir})
|
||||
AC_ARG_WITH(tclinclude, [ --with-tclinclude=DIR Directory where tcl private headers are], with_tclinclude=${withval})
|
||||
AC_CACHE_VAL(ac_cv_c_tclh,[
|
||||
# first check to see if --with-tclinclude was specified
|
||||
if test x"${with_tclinclude}" != x ; then
|
||||
if test -f ${with_tclinclude}/tclInt.h ; then
|
||||
ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
|
||||
elif test -f ${with_tclinclude}/generic/tclInt.h ; then
|
||||
ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
|
||||
else
|
||||
AC_MSG_ERROR([${with_tclinclude} directory doesn't contain private headers])
|
||||
fi
|
||||
fi
|
||||
|
||||
# next check if it came with Tcl configuration file
|
||||
if test x"${ac_cv_c_tclconfig}" = x ; then
|
||||
if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
|
||||
ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/..; pwd)`
|
||||
fi
|
||||
fi
|
||||
|
||||
# next check in private source directory
|
||||
#
|
||||
# since ls returns lowest version numbers first, reverse its output
|
||||
if test x"${ac_cv_c_tclh}" = x ; then
|
||||
for i in \
|
||||
${srcdir}/../tcl \
|
||||
`ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` \
|
||||
${srcdir}/../../tcl \
|
||||
`ls -dr ${srcdir}/../../tcl[[7-9]]* 2>/dev/null` \
|
||||
${srcdir}/../../../tcl \
|
||||
`ls -dr ${srcdir}/../../../tcl[[7-9]]* 2>/dev/null ` ; do
|
||||
if test -f $i/generic/tclInt.h ; then
|
||||
ac_cv_c_tclh=`(cd $i/generic; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# finally check in a few common install locations
|
||||
#
|
||||
# since ls returns lowest version numbers first, reverse its output
|
||||
if test x"${ac_cv_c_tclh}" = x ; then
|
||||
for i in \
|
||||
`ls -dr /usr/local/src/tcl[[7-9]]* 2>/dev/null` \
|
||||
`ls -dr /usr/local/lib/tcl[[7-9]]* 2>/dev/null` \
|
||||
/usr/local/src/tcl \
|
||||
/usr/local/lib/tcl \
|
||||
${prefix}/include ; do
|
||||
if test -f $i/generic/tclInt.h ; then
|
||||
ac_cv_c_tclh=`(cd $i/generic; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# see if one is installed
|
||||
if test x"${ac_cv_c_tclh}" = x ; then
|
||||
AC_HEADER_CHECK(tclInt.h, ac_cv_c_tclh=installed, ac_cv_c_tclh="")
|
||||
fi
|
||||
])
|
||||
if test x"${ac_cv_c_tclh}" = x ; then
|
||||
TCLHDIR="# no Tcl private headers found"
|
||||
AC_MSG_ERROR([Can't find Tcl private headers])
|
||||
fi
|
||||
if test x"${ac_cv_c_tclh}" != x ; then
|
||||
no_tcl=""
|
||||
if test x"${ac_cv_c_tclh}" = x"installed" ; then
|
||||
AC_MSG_RESULT([is installed])
|
||||
TCLHDIR=""
|
||||
else
|
||||
AC_MSG_RESULT([found in ${ac_cv_c_tclh}])
|
||||
# this hack is cause the TCLHDIR won't print if there is a "-I" in it.
|
||||
TCLHDIR="-I${ac_cv_c_tclh}"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(TCLHDIR)
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_TCLCONFIG, [
|
||||
#
|
||||
# Ok, lets find the tcl configuration
|
||||
# First, look for one uninstalled.
|
||||
# the alternative search directory is invoked by --with-tclconfig
|
||||
#
|
||||
|
||||
if test x"${no_tcl}" = x ; then
|
||||
# we reset no_tcl in case something fails here
|
||||
no_tcl=true
|
||||
AC_ARG_WITH(tclconfig, [ --with-tclconfig=DIR Directory containing tcl configuration (tclConfig.sh)],
|
||||
with_tclconfig=${withval})
|
||||
AC_MSG_CHECKING([for Tcl configuration])
|
||||
AC_CACHE_VAL(ac_cv_c_tclconfig,[
|
||||
|
||||
# First check to see if --with-tclconfig was specified.
|
||||
if test x"${with_tclconfig}" != x ; then
|
||||
if test -f "${with_tclconfig}/tclConfig.sh" ; then
|
||||
ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
|
||||
else
|
||||
AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
|
||||
fi
|
||||
fi
|
||||
|
||||
# then check for a private Tcl installation
|
||||
if test x"${ac_cv_c_tclconfig}" = x ; then
|
||||
for i in \
|
||||
../tcl \
|
||||
`ls -dr ../tcl[[7-9]]* 2>/dev/null` \
|
||||
../../tcl \
|
||||
`ls -dr ../../tcl[[7-9]]* 2>/dev/null` \
|
||||
../../../tcl \
|
||||
`ls -dr ../../../tcl[[7-9]]* 2>/dev/null` ; do
|
||||
if test -f "$i/${configdir}/tclConfig.sh" ; then
|
||||
ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few common install locations
|
||||
if test x"${ac_cv_c_tclconfig}" = x ; then
|
||||
for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
|
||||
if test -f "$i/tclConfig.sh" ; then
|
||||
ac_cv_c_tclconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few other private locations
|
||||
if test x"${ac_cv_c_tclconfig}" = x ; then
|
||||
for i in \
|
||||
${srcdir}/../tcl \
|
||||
`ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` ; do
|
||||
if test -f "$i/${configdir}/tclConfig.sh" ; then
|
||||
ac_cv_c_tclconfig=`(cd $i/${configdir}; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
if test x"${ac_cv_c_tclconfig}" = x ; then
|
||||
TCLCONFIG="# no Tcl configs found"
|
||||
AC_MSG_WARN(Can't find Tcl configuration definitions)
|
||||
else
|
||||
no_tcl=
|
||||
TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
|
||||
AC_MSG_RESULT(found $TCLCONFIG)
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
# Defined as a separate macro so we don't have to cache the values
|
||||
# from PATH_TCLCONFIG (because this can also be cached).
|
||||
AC_DEFUN(CY_AC_LOAD_TCLCONFIG, [
|
||||
. $TCLCONFIG
|
||||
|
||||
AC_SUBST(TCL_VERSION)
|
||||
AC_SUBST(TCL_MAJOR_VERSION)
|
||||
AC_SUBST(TCL_MINOR_VERSION)
|
||||
AC_SUBST(TCL_CC)
|
||||
AC_SUBST(TCL_DEFS)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TCL_LIB_FILE)
|
||||
|
||||
dnl don't export, not used outside of configure
|
||||
dnl AC_SUBST(TCL_LIBS)
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TCL_PREFIX)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TCL_EXEC_PREFIX)
|
||||
|
||||
AC_SUBST(TCL_SHLIB_CFLAGS)
|
||||
AC_SUBST(TCL_SHLIB_LD)
|
||||
dnl don't export, not used outside of configure
|
||||
AC_SUBST(TCL_SHLIB_LD_LIBS)
|
||||
AC_SUBST(TCL_SHLIB_SUFFIX)
|
||||
dnl not used, don't export to save symbols
|
||||
AC_SUBST(TCL_DL_LIBS)
|
||||
AC_SUBST(TCL_LD_FLAGS)
|
||||
dnl don't export, not used outside of configure
|
||||
AC_SUBST(TCL_LD_SEARCH_FLAGS)
|
||||
AC_SUBST(TCL_COMPAT_OBJS)
|
||||
AC_SUBST(TCL_RANLIB)
|
||||
AC_SUBST(TCL_BUILD_LIB_SPEC)
|
||||
AC_SUBST(TCL_LIB_SPEC)
|
||||
AC_SUBST(TCL_LIB_VERSIONS_OK)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TCL_SHARED_LIB_SUFFIX)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TCL_UNSHARED_LIB_SUFFIX)
|
||||
])
|
||||
|
||||
# Warning: Tk definitions are very similar to Tcl definitions but
|
||||
# are not precisely the same. There are a couple of differences,
|
||||
# so don't do changes to Tcl thinking you can cut and paste it do
|
||||
# the Tk differences and later simply substitute "Tk" for "Tcl".
|
||||
# Known differences:
|
||||
# - Acceptable Tcl major version #s is 7-9 while Tk is 4-9
|
||||
# - Searching for Tcl includes looking for tclInt.h, Tk looks for tk.h
|
||||
# - Computing major/minor versions is different because Tk depends on
|
||||
# headers to Tcl, Tk, and X.
|
||||
# - Symbols in tkConfig.sh are different than tclConfig.sh
|
||||
# - Acceptable for Tk to be missing but not Tcl.
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_TKH, [
|
||||
#
|
||||
# Ok, lets find the tk source trees so we can use the headers
|
||||
# If the directory (presumably symlink) named "tk" exists, use that one
|
||||
# in preference to any others. Same logic is used when choosing library
|
||||
# and again with Tcl. The search order is the best place to look first, then in
|
||||
# decreasing significance. The loop breaks if the trigger file is found.
|
||||
# Note the gross little conversion here of srcdir by cd'ing to the found
|
||||
# directory. This converts the path from a relative to an absolute, so
|
||||
# recursive cache variables for the path will work right. We check all
|
||||
# the possible paths in one loop rather than many seperate loops to speed
|
||||
# things up.
|
||||
# the alternative search directory is involked by --with-tkinclude
|
||||
#
|
||||
no_tk=true
|
||||
AC_MSG_CHECKING(for Tk private headers)
|
||||
AC_ARG_WITH(tkinclude, [ --with-tkinclude=DIR Directory where tk private headers are], with_tkinclude=${withval})
|
||||
AC_CACHE_VAL(ac_cv_c_tkh,[
|
||||
# first check to see if --with-tkinclude was specified
|
||||
if test x"${with_tkinclude}" != x ; then
|
||||
if test -f ${with_tkinclude}/tk.h ; then
|
||||
ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
|
||||
elif test -f ${with_tkinclude}/generic/tk.h ; then
|
||||
ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)`
|
||||
else
|
||||
AC_MSG_ERROR([${with_tkinclude} directory doesn't contain private headers])
|
||||
fi
|
||||
fi
|
||||
|
||||
# next check if it came with Tk configuration file
|
||||
if test x"${ac_cv_c_tkconfig}" = x ; then
|
||||
if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then
|
||||
ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/..; pwd)`
|
||||
fi
|
||||
fi
|
||||
|
||||
# next check in private source directory
|
||||
#
|
||||
# since ls returns lowest version numbers first, reverse its output
|
||||
if test x"${ac_cv_c_tkh}" = x ; then
|
||||
for i in \
|
||||
${srcdir}/../tk \
|
||||
`ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` \
|
||||
${srcdir}/../../tk \
|
||||
`ls -dr ${srcdir}/../../tk[[4-9]]* 2>/dev/null` \
|
||||
${srcdir}/../../../tk \
|
||||
`ls -dr ${srcdir}/../../../tk[[4-9]]* 2>/dev/null ` ; do
|
||||
if test -f $i/generic/tk.h ; then
|
||||
ac_cv_c_tkh=`(cd $i/generic; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# finally check in a few common install locations
|
||||
#
|
||||
# since ls returns lowest version numbers first, reverse its output
|
||||
if test x"${ac_cv_c_tkh}" = x ; then
|
||||
for i in \
|
||||
`ls -dr /usr/local/src/tk[[4-9]]* 2>/dev/null` \
|
||||
`ls -dr /usr/local/lib/tk[[4-9]]* 2>/dev/null` \
|
||||
/usr/local/src/tk \
|
||||
/usr/local/lib/tk \
|
||||
${prefix}/include ; do
|
||||
if test -f $i/generic/tk.h ; then
|
||||
ac_cv_c_tkh=`(cd $i/generic; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# see if one is installed
|
||||
if test x"${ac_cv_c_tkh}" = x ; then
|
||||
AC_HEADER_CHECK(tk.h, ac_cv_c_tkh=installed, ac_cv_c_tkh="")
|
||||
fi
|
||||
])
|
||||
if test x"${ac_cv_c_tkh}" != x ; then
|
||||
no_tk=""
|
||||
if test x"${ac_cv_c_tkh}" = x"installed" ; then
|
||||
AC_MSG_RESULT([is installed])
|
||||
TKHDIR=""
|
||||
else
|
||||
AC_MSG_RESULT([found in ${ac_cv_c_tkh}])
|
||||
# this hack is cause the TKHDIR won't print if there is a "-I" in it.
|
||||
TKHDIR="-I${ac_cv_c_tkh}"
|
||||
fi
|
||||
else
|
||||
TKHDIR="# no Tk directory found"
|
||||
AC_MSG_WARN([Can't find Tk private headers])
|
||||
no_tk=true
|
||||
fi
|
||||
|
||||
AC_SUBST(TKHDIR)
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_TKCONFIG, [
|
||||
#
|
||||
# Ok, lets find the tk configuration
|
||||
# First, look for one uninstalled.
|
||||
# the alternative search directory is invoked by --with-tkconfig
|
||||
#
|
||||
|
||||
if test x"${no_tk}" = x ; then
|
||||
# we reset no_tk in case something fails here
|
||||
no_tk=true
|
||||
AC_ARG_WITH(tkconfig, [ --with-tkconfig=DIR Directory containing tk configuration (tkConfig.sh)],
|
||||
with_tkconfig=${withval})
|
||||
AC_MSG_CHECKING([for Tk configuration])
|
||||
AC_CACHE_VAL(ac_cv_c_tkconfig,[
|
||||
|
||||
# First check to see if --with-tkconfig was specified.
|
||||
if test x"${with_tkconfig}" != x ; then
|
||||
if test -f "${with_tkconfig}/tkConfig.sh" ; then
|
||||
ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
|
||||
else
|
||||
AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
|
||||
fi
|
||||
fi
|
||||
|
||||
# then check for a private Tk library
|
||||
if test x"${ac_cv_c_tkconfig}" = x ; then
|
||||
for i in \
|
||||
../tk \
|
||||
`ls -dr ../tk[[4-9]]* 2>/dev/null` \
|
||||
../../tk \
|
||||
`ls -dr ../../tk[[4-9]]* 2>/dev/null` \
|
||||
../../../tk \
|
||||
`ls -dr ../../../tk[[4-9]]* 2>/dev/null` ; do
|
||||
if test -f "$i/${configdir}/tkConfig.sh" ; then
|
||||
ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few common install locations
|
||||
if test x"${ac_cv_c_tkconfig}" = x ; then
|
||||
for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
|
||||
if test -f "$i/tkConfig.sh" ; then
|
||||
ac_cv_c_tkconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few other private locations
|
||||
if test x"${ac_cv_c_tkconfig}" = x ; then
|
||||
for i in \
|
||||
${srcdir}/../tk \
|
||||
`ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` ; do
|
||||
if test -f "$i/${configdir}/tkConfig.sh" ; then
|
||||
ac_cv_c_tkconfig=`(cd $i/${configdir}; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
if test x"${ac_cv_c_tkconfig}" = x ; then
|
||||
TKCONFIG="# no Tk configs found"
|
||||
AC_MSG_WARN(Can't find Tk configuration definitions)
|
||||
else
|
||||
no_tk=
|
||||
TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh
|
||||
AC_MSG_RESULT(found $TKCONFIG)
|
||||
fi
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
# Defined as a separate macro so we don't have to cache the values
|
||||
# from PATH_TKCONFIG (because this can also be cached).
|
||||
AC_DEFUN(CY_AC_LOAD_TKCONFIG, [
|
||||
if test -f "$TKCONFIG" ; then
|
||||
. $TKCONFIG
|
||||
fi
|
||||
|
||||
AC_SUBST(TK_VERSION)
|
||||
dnl not actually used, don't export to save symbols
|
||||
dnl AC_SUBST(TK_MAJOR_VERSION)
|
||||
dnl AC_SUBST(TK_MINOR_VERSION)
|
||||
AC_SUBST(TK_DEFS)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TK_LIB_FILE)
|
||||
|
||||
dnl not used outside of configure
|
||||
dnl AC_SUBST(TK_LIBS)
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TK_PREFIX)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TK_EXEC_PREFIX)
|
||||
|
||||
AC_SUBST(TK_BUILD_INCLUDES)
|
||||
AC_SUBST(TK_XINCLUDES)
|
||||
AC_SUBST(TK_XLIBSW)
|
||||
AC_SUBST(TK_BUILD_LIB_SPEC)
|
||||
AC_SUBST(TK_LIB_SPEC)
|
||||
])
|
||||
|
||||
# check for Itcl headers.
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_ITCLCONFIG, [
|
||||
#
|
||||
# Ok, lets find the itcl configuration
|
||||
# First, look for one uninstalled.
|
||||
# the alternative search directory is invoked by --with-itclconfig
|
||||
#
|
||||
|
||||
if test x"${no_itcl}" = x ; then
|
||||
# we reset no_itcl in case something fails here
|
||||
no_itcl=true
|
||||
AC_ARG_WITH(itclconfig, [ --with-itclconfig Directory containing itcl configuration (itclConfig.sh)],
|
||||
with_itclconfig=${withval})
|
||||
AC_MSG_CHECKING([for Itcl configuration])
|
||||
AC_CACHE_VAL(ac_cv_c_itclconfig,[
|
||||
|
||||
# First check to see if --with-itclconfig was specified.
|
||||
if test x"${with_itclconfig}" != x ; then
|
||||
if test -f "${with_itclconfig}/itclConfig.sh" ; then
|
||||
ac_cv_c_itclconfig=`(cd ${with_itclconfig}; pwd)`
|
||||
else
|
||||
AC_MSG_ERROR([${with_itclconfig} directory doesn't contain itclConfig.sh])
|
||||
fi
|
||||
fi
|
||||
|
||||
# then check for a private Itcl library
|
||||
if test x"${ac_cv_c_itclconfig}" = x ; then
|
||||
for i in \
|
||||
../itcl/itcl \
|
||||
`ls -dr ../itcl[[4-9]]*/itcl 2>/dev/null` \
|
||||
../../itcl \
|
||||
`ls -dr ../../itcl[[4-9]]*/itcl 2>/dev/null` \
|
||||
../../../itcl \
|
||||
`ls -dr ../../../itcl[[4-9]]*/itcl 2>/dev/null` ; do
|
||||
if test -f "$i/itclConfig.sh" ; then
|
||||
ac_cv_c_itclconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few common install locations
|
||||
if test x"${ac_cv_c_itclconfig}" = x ; then
|
||||
for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
|
||||
if test -f "$i/itclConfig.sh" ; then
|
||||
ac_cv_c_itclconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few other private locations
|
||||
if test x"${ac_cv_c_itclconfig}" = x ; then
|
||||
for i in \
|
||||
${srcdir}/../itcl/itcl \
|
||||
`ls -dr ${srcdir}/../itcl[[4-9]]*/itcl 2>/dev/null` ; do
|
||||
if test -f "$i/itclConfig.sh" ; then
|
||||
ac_cv_c_itclconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
if test x"${ac_cv_c_itclconfig}" = x ; then
|
||||
ITCLCONFIG="# no Itcl configs found"
|
||||
AC_MSG_WARN(Can't find Itcl configuration definitions)
|
||||
else
|
||||
no_itcl=
|
||||
ITCLCONFIG=${ac_cv_c_itclconfig}/itclConfig.sh
|
||||
AC_MSG_RESULT(found $ITCLCONFIG)
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
# Defined as a separate macro so we don't have to cache the values
|
||||
# from PATH_ITCLCONFIG (because this can also be cached).
|
||||
AC_DEFUN(CY_AC_LOAD_ITCLCONFIG, [
|
||||
if test -f "$ITCLCONFIG" ; then
|
||||
. $ITCLCONFIG
|
||||
fi
|
||||
|
||||
AC_SUBST(ITCL_VERSION)
|
||||
dnl not actually used, don't export to save symbols
|
||||
dnl AC_SUBST(ITCL_MAJOR_VERSION)
|
||||
dnl AC_SUBST(ITCL_MINOR_VERSION)
|
||||
AC_SUBST(ITCL_DEFS)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(ITCL_LIB_FILE)
|
||||
|
||||
dnl not used outside of configure
|
||||
dnl AC_SUBST(ITCL_LIBS)
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(ITCL_PREFIX)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(ITCL_EXEC_PREFIX)
|
||||
|
||||
AC_SUBST(ITCL_BUILD_INCLUDES)
|
||||
AC_SUBST(ITCL_BUILD_LIB_SPEC)
|
||||
AC_SUBST(ITCL_LIB_SPEC)
|
||||
])
|
||||
|
||||
# check for Itcl headers.
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_ITCLH, [
|
||||
AC_MSG_CHECKING(for Itcl private headers. srcdir=${srcdir})
|
||||
if test x"${ac_cv_c_itclh}" = x ; then
|
||||
for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itcl; do
|
||||
if test -f $i/generic/itcl.h ; then
|
||||
ac_cv_c_itclh=`(cd $i/generic; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test x"${ac_cv_c_itclh}" = x ; then
|
||||
ITCLHDIR="# no Itcl private headers found"
|
||||
AC_MSG_ERROR([Can't find Itcl private headers])
|
||||
fi
|
||||
if test x"${ac_cv_c_itclh}" != x ; then
|
||||
ITCLHDIR="-I${ac_cv_c_itclh}"
|
||||
fi
|
||||
# should always be here
|
||||
# ITCLLIB="../itcl/itcl/unix/libitcl.a"
|
||||
AC_SUBST(ITCLHDIR)
|
||||
#AC_SUBST(ITCLLIB)
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_ITKCONFIG, [
|
||||
#
|
||||
# Ok, lets find the itk configuration
|
||||
# First, look for one uninstalled.
|
||||
# the alternative search directory is invoked by --with-itkconfig
|
||||
#
|
||||
|
||||
if test x"${no_itk}" = x ; then
|
||||
# we reset no_itk in case something fails here
|
||||
no_itk=true
|
||||
AC_ARG_WITH(itkconfig, [ --with-itkconfig Directory containing itk configuration (itkConfig.sh)],
|
||||
with_itkconfig=${withval})
|
||||
AC_MSG_CHECKING([for Itk configuration])
|
||||
AC_CACHE_VAL(ac_cv_c_itkconfig,[
|
||||
|
||||
# First check to see if --with-itkconfig was specified.
|
||||
if test x"${with_itkconfig}" != x ; then
|
||||
if test -f "${with_itkconfig}/itkConfig.sh" ; then
|
||||
ac_cv_c_itkconfig=`(cd ${with_itkconfig}; pwd)`
|
||||
else
|
||||
AC_MSG_ERROR([${with_itkconfig} directory doesn't contain itkConfig.sh])
|
||||
fi
|
||||
fi
|
||||
|
||||
# then check for a private Itk library
|
||||
if test x"${ac_cv_c_itkconfig}" = x ; then
|
||||
for i in \
|
||||
../itcl/itk \
|
||||
`ls -dr ../itcl[[4-9]]*/itk 2>/dev/null` \
|
||||
../../itk \
|
||||
`ls -dr ../../itcl[[4-9]]*/itk 2>/dev/null` \
|
||||
../../../itk \
|
||||
`ls -dr ../../../itcl[[4-9]]*/itk 2>/dev/null` ; do
|
||||
if test -f "$i/itkConfig.sh" ; then
|
||||
ac_cv_c_itkconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few common install locations
|
||||
if test x"${ac_cv_c_itkconfig}" = x ; then
|
||||
for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
|
||||
if test -f "$i/itkConfig.sh" ; then
|
||||
ac_cv_c_itkconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few other private locations
|
||||
if test x"${ac_cv_c_itkconfig}" = x ; then
|
||||
for i in \
|
||||
${srcdir}/../itcl/itk \
|
||||
`ls -dr ${srcdir}/../itcl[[4-9]]*/itk 2>/dev/null` ; do
|
||||
if test -f "$i/itkConfig.sh" ; then
|
||||
ac_cv_c_itkconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
if test x"${ac_cv_c_itkconfig}" = x ; then
|
||||
ITKCONFIG="# no Itk configs found"
|
||||
AC_MSG_WARN(Can't find Itk configuration definitions)
|
||||
else
|
||||
no_itk=
|
||||
ITKCONFIG=${ac_cv_c_itkconfig}/itkConfig.sh
|
||||
AC_MSG_RESULT(found $ITKCONFIG)
|
||||
fi
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
# Defined as a separate macro so we don't have to cache the values
|
||||
# from PATH_ITKCONFIG (because this can also be cached).
|
||||
AC_DEFUN(CY_AC_LOAD_ITKCONFIG, [
|
||||
if test -f "$ITKCONFIG" ; then
|
||||
. $ITKCONFIG
|
||||
fi
|
||||
|
||||
AC_SUBST(ITK_VERSION)
|
||||
dnl not actually used, don't export to save symbols
|
||||
dnl AC_SUBST(ITK_MAJOR_VERSION)
|
||||
dnl AC_SUBST(ITK_MINOR_VERSION)
|
||||
AC_SUBST(ITK_DEFS)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(ITK_LIB_FILE)
|
||||
|
||||
dnl not used outside of configure
|
||||
dnl AC_SUBST(ITK_LIBS)
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(ITK_PREFIX)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(ITK_EXEC_PREFIX)
|
||||
|
||||
AC_SUBST(ITK_BUILD_INCLUDES)
|
||||
AC_SUBST(ITK_BUILD_LIB_SPEC)
|
||||
AC_SUBST(ITK_LIB_SPEC)
|
||||
])
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_ITKH, [
|
||||
AC_MSG_CHECKING(for Itk private headers. srcdir=${srcdir})
|
||||
if test x"${ac_cv_c_itkh}" = x ; then
|
||||
for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ${srcdir}/../itcl/itk; do
|
||||
if test -f $i/generic/itk.h ; then
|
||||
ac_cv_c_itkh=`(cd $i/generic; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test x"${ac_cv_c_itkh}" = x ; then
|
||||
ITKHDIR="# no Itk private headers found"
|
||||
AC_MSG_ERROR([Can't find Itk private headers])
|
||||
fi
|
||||
if test x"${ac_cv_c_itkh}" != x ; then
|
||||
ITKHDIR="-I${ac_cv_c_itkh}"
|
||||
fi
|
||||
# should always be here
|
||||
# ITKLIB="../itcl/itk/unix/libitk.a"
|
||||
AC_SUBST(ITKHDIR)
|
||||
#AC_SUBST(ITKLIB)
|
||||
])
|
||||
|
||||
# check for Tix headers.
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_TIXH, [
|
||||
AC_MSG_CHECKING(for Tix private headers. srcdir=${srcdir})
|
||||
if test x"${ac_cv_c_tixh}" = x ; then
|
||||
for i in ${srcdir}/../tix ${srcdir}/../../tix ${srcdir}/../../../tix ; do
|
||||
if test -f $i/generic/tix.h ; then
|
||||
ac_cv_c_tixh=`(cd $i/generic; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test x"${ac_cv_c_tixh}" = x ; then
|
||||
TIXHDIR="# no Tix private headers found"
|
||||
AC_MSG_ERROR([Can't find Tix private headers])
|
||||
fi
|
||||
if test x"${ac_cv_c_tixh}" != x ; then
|
||||
TIXHDIR="-I${ac_cv_c_tixh}"
|
||||
fi
|
||||
AC_SUBST(TIXHDIR)
|
||||
])
|
||||
|
||||
AC_DEFUN(CY_AC_PATH_TIXCONFIG, [
|
||||
#
|
||||
# Ok, lets find the tix configuration
|
||||
# First, look for one uninstalled.
|
||||
# the alternative search directory is invoked by --with-itkconfig
|
||||
#
|
||||
|
||||
if test x"${no_tix}" = x ; then
|
||||
# we reset no_tix in case something fails here
|
||||
no_tix=true
|
||||
AC_ARG_WITH(tixconfig, [ --with-tixconfig Directory containing tix configuration (tixConfig.sh)],
|
||||
with_tixconfig=${withval})
|
||||
AC_MSG_CHECKING([for Tix configuration])
|
||||
AC_CACHE_VAL(ac_cv_c_tixconfig,[
|
||||
|
||||
# First check to see if --with-tixconfig was specified.
|
||||
if test x"${with_tixconfig}" != x ; then
|
||||
if test -f "${with_tixconfig}/tixConfig.sh" ; then
|
||||
ac_cv_c_tixconfig=`(cd ${with_tixconfig}; pwd)`
|
||||
else
|
||||
AC_MSG_ERROR([${with_tixconfig} directory doesn't contain tixConfig.sh])
|
||||
fi
|
||||
fi
|
||||
|
||||
# then check for a private Tix library
|
||||
if test x"${ac_cv_c_tixconfig}" = x ; then
|
||||
for i in \
|
||||
../tix \
|
||||
`ls -dr ../tix 2>/dev/null` \
|
||||
../../tix \
|
||||
`ls -dr ../../tix 2>/dev/null` \
|
||||
../../../tix \
|
||||
`ls -dr ../../../tix 2>/dev/null` ; do
|
||||
echo "**** Looking at $i - with ${configdir}"
|
||||
if test -f "$i/tixConfig.sh" ; then
|
||||
ac_cv_c_tixconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few common install locations
|
||||
if test x"${ac_cv_c_tixconfig}" = x ; then
|
||||
for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
|
||||
echo "**** Looking at $i"
|
||||
if test -f "$i/tixConfig.sh" ; then
|
||||
ac_cv_c_tixconfig=`(cd $i; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# check in a few other private locations
|
||||
echo "**** Other private locations"
|
||||
if test x"${ac_cv_c_tixconfig}" = x ; then
|
||||
for i in \
|
||||
${srcdir}/../tix \
|
||||
`ls -dr ${srcdir}/../tix 2>/dev/null` ; do
|
||||
echo "**** Looking at $i - with ${configdir}"
|
||||
if test -f "$i/${configdir}/tixConfig.sh" ; then
|
||||
ac_cv_c_tixconfig=`(cd $i/${configdir}; pwd)`
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
if test x"${ac_cv_c_tixconfig}" = x ; then
|
||||
TIXCONFIG="# no Tix configs found"
|
||||
AC_MSG_WARN(Can't find Tix configuration definitions)
|
||||
else
|
||||
no_tix=
|
||||
TIXCONFIG=${ac_cv_c_tixconfig}/tixConfig.sh
|
||||
AC_MSG_RESULT(found $TIXCONFIG)
|
||||
fi
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
# Defined as a separate macro so we don't have to cache the values
|
||||
# from PATH_TIXCONFIG (because this can also be cached).
|
||||
AC_DEFUN(CY_AC_LOAD_TIXCONFIG, [
|
||||
if test -f "$TIXCONFIG" ; then
|
||||
. $TIXCONFIG
|
||||
fi
|
||||
|
||||
AC_SUBST(TIX_VERSION)
|
||||
dnl not actually used, don't export to save symbols
|
||||
dnl AC_SUBST(TIX_MAJOR_VERSION)
|
||||
dnl AC_SUBST(TIX_MINOR_VERSION)
|
||||
dnl AC_SUBST(TIX_DEFS)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl dnl AC_SUBST(TIX_LIB_FILE)
|
||||
|
||||
dnl not used outside of configure
|
||||
dnl AC_SUBST(TIX_LIBS)
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TIX_PREFIX)
|
||||
|
||||
dnl not used, don't export to save symbols
|
||||
dnl AC_SUBST(TIX_EXEC_PREFIX)
|
||||
|
||||
dnl AC_SUBST(TIX_BUILD_INCLUDES)
|
||||
AC_SUBST(TIX_BUILD_LIB_SPEC)
|
||||
dnl AC_SUBST(TIX_LIB_SPEC)
|
||||
])
|
||||
|
||||
dnl sinclude(../gettext.m4) already included by bfd/acinclude.m4
|
||||
dnl The lines below arrange for aclocal not to bring gettext.m4's
|
||||
dnl CY_GNU_GETTEXT into aclocal.m4.
|
||||
ifelse(yes,no,[
|
||||
AC_DEFUN([CY_GNU_GETTEXT],)
|
||||
])
|
||||
1020
gdb/aclocal.m4
vendored
1020
gdb/aclocal.m4
vendored
File diff suppressed because it is too large
Load Diff
308
gdb/alpha-nat.c
308
gdb/alpha-nat.c
@@ -1,308 +0,0 @@
|
||||
/* Low level Alpha interface, for GDB when running native.
|
||||
Copyright 1993, 1995, 1996, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
#include "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "regcache.h"
|
||||
#include <sys/ptrace.h>
|
||||
#ifdef __linux__
|
||||
#include <asm/reg.h>
|
||||
#include <alpha/ptrace.h>
|
||||
#else
|
||||
#include <alpha/coreregs.h>
|
||||
#endif
|
||||
#include <sys/user.h>
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
|
||||
static void fetch_osf_core_registers (char *, unsigned, int, CORE_ADDR);
|
||||
static void fetch_elf_core_registers (char *, unsigned, int, CORE_ADDR);
|
||||
|
||||
/* Size of elements in jmpbuf */
|
||||
|
||||
#define JB_ELEMENT_SIZE 8
|
||||
|
||||
/* The definition for JB_PC in machine/reg.h is wrong.
|
||||
And we can't get at the correct definition in setjmp.h as it is
|
||||
not always available (eg. if _POSIX_SOURCE is defined which is the
|
||||
default). As the defintion is unlikely to change (see comment
|
||||
in <setjmp.h>, define the correct value here. */
|
||||
|
||||
#undef JB_PC
|
||||
#define JB_PC 2
|
||||
|
||||
/* Figure out where the longjmp will land.
|
||||
We expect the first arg to be a pointer to the jmp_buf structure from which
|
||||
we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
|
||||
This routine returns true on success. */
|
||||
|
||||
int
|
||||
get_longjmp_target (CORE_ADDR *pc)
|
||||
{
|
||||
CORE_ADDR jb_addr;
|
||||
char raw_buffer[MAX_REGISTER_RAW_SIZE];
|
||||
|
||||
jb_addr = read_register (A0_REGNUM);
|
||||
|
||||
if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, raw_buffer,
|
||||
sizeof (CORE_ADDR)))
|
||||
return 0;
|
||||
|
||||
*pc = extract_address (raw_buffer, sizeof (CORE_ADDR));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Extract the register values out of the core file and store
|
||||
them where `read_register' will find them.
|
||||
|
||||
CORE_REG_SECT points to the register values themselves, read into memory.
|
||||
CORE_REG_SIZE is the size of that area.
|
||||
WHICH says which set of registers we are handling (0 = int, 2 = float
|
||||
on machines where they are discontiguous).
|
||||
REG_ADDR is the offset from u.u_ar0 to the register values relative to
|
||||
core_reg_sect. This is used with old-fashioned core files to
|
||||
locate the registers in a large upage-plus-stack ".reg" section.
|
||||
Original upage address X is at location core_reg_sect+x+reg_addr.
|
||||
*/
|
||||
|
||||
static void
|
||||
fetch_osf_core_registers (char *core_reg_sect, unsigned core_reg_size,
|
||||
int which, CORE_ADDR reg_addr)
|
||||
{
|
||||
register int regno;
|
||||
register int addr;
|
||||
int bad_reg = -1;
|
||||
|
||||
/* Table to map a gdb regnum to an index in the core register
|
||||
section. The floating point register values are garbage in
|
||||
OSF/1.2 core files. OSF5 uses different names for the register
|
||||
enum list, need to handle two cases. The actual values are the
|
||||
same. */
|
||||
static int core_reg_mapping[NUM_REGS] =
|
||||
{
|
||||
#ifdef NCF_REGS
|
||||
#define EFL NCF_REGS
|
||||
CF_V0, CF_T0, CF_T1, CF_T2, CF_T3, CF_T4, CF_T5, CF_T6,
|
||||
CF_T7, CF_S0, CF_S1, CF_S2, CF_S3, CF_S4, CF_S5, CF_S6,
|
||||
CF_A0, CF_A1, CF_A2, CF_A3, CF_A4, CF_A5, CF_T8, CF_T9,
|
||||
CF_T10, CF_T11, CF_RA, CF_T12, CF_AT, CF_GP, CF_SP, -1,
|
||||
EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7,
|
||||
EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15,
|
||||
EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23,
|
||||
EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31,
|
||||
CF_PC, -1
|
||||
#else
|
||||
#define EFL (EF_SIZE / 8)
|
||||
EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6,
|
||||
EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6,
|
||||
EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9,
|
||||
EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1,
|
||||
EFL + 0, EFL + 1, EFL + 2, EFL + 3, EFL + 4, EFL + 5, EFL + 6, EFL + 7,
|
||||
EFL + 8, EFL + 9, EFL + 10, EFL + 11, EFL + 12, EFL + 13, EFL + 14, EFL + 15,
|
||||
EFL + 16, EFL + 17, EFL + 18, EFL + 19, EFL + 20, EFL + 21, EFL + 22, EFL + 23,
|
||||
EFL + 24, EFL + 25, EFL + 26, EFL + 27, EFL + 28, EFL + 29, EFL + 30, EFL + 31,
|
||||
EF_PC, -1
|
||||
#endif
|
||||
};
|
||||
static char zerobuf[MAX_REGISTER_RAW_SIZE] =
|
||||
{0};
|
||||
|
||||
for (regno = 0; regno < NUM_REGS; regno++)
|
||||
{
|
||||
if (CANNOT_FETCH_REGISTER (regno))
|
||||
{
|
||||
supply_register (regno, zerobuf);
|
||||
continue;
|
||||
}
|
||||
addr = 8 * core_reg_mapping[regno];
|
||||
if (addr < 0 || addr >= core_reg_size)
|
||||
{
|
||||
if (bad_reg < 0)
|
||||
bad_reg = regno;
|
||||
}
|
||||
else
|
||||
{
|
||||
supply_register (regno, core_reg_sect + addr);
|
||||
}
|
||||
}
|
||||
if (bad_reg >= 0)
|
||||
{
|
||||
error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size,
|
||||
int which, CORE_ADDR reg_addr)
|
||||
{
|
||||
if (core_reg_size < 32 * 8)
|
||||
{
|
||||
error ("Core file register section too small (%u bytes).", core_reg_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (which == 2)
|
||||
{
|
||||
/* The FPU Registers. */
|
||||
memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], core_reg_sect, 31 * 8);
|
||||
memset (®isters[REGISTER_BYTE (FP0_REGNUM + 31)], 0, 8);
|
||||
memset (®ister_valid[FP0_REGNUM], 1, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The General Registers. */
|
||||
memcpy (®isters[REGISTER_BYTE (V0_REGNUM)], core_reg_sect, 31 * 8);
|
||||
memcpy (®isters[REGISTER_BYTE (PC_REGNUM)], core_reg_sect + 31 * 8, 8);
|
||||
memset (®isters[REGISTER_BYTE (ZERO_REGNUM)], 0, 8);
|
||||
memset (®ister_valid[V0_REGNUM], 1, 32);
|
||||
register_valid[PC_REGNUM] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Map gdb internal register number to a ptrace ``address''.
|
||||
These ``addresses'' are defined in <sys/ptrace.h> */
|
||||
|
||||
#define REGISTER_PTRACE_ADDR(regno) \
|
||||
(regno < FP0_REGNUM ? GPR_BASE + (regno) \
|
||||
: regno == PC_REGNUM ? PC \
|
||||
: regno >= FP0_REGNUM ? FPR_BASE + ((regno) - FP0_REGNUM) \
|
||||
: 0)
|
||||
|
||||
/* Return the ptrace ``address'' of register REGNO. */
|
||||
|
||||
CORE_ADDR
|
||||
register_addr (int regno, CORE_ADDR blockend)
|
||||
{
|
||||
return REGISTER_PTRACE_ADDR (regno);
|
||||
}
|
||||
|
||||
int
|
||||
kernel_u_size (void)
|
||||
{
|
||||
return (sizeof (struct user));
|
||||
}
|
||||
|
||||
#if defined(USE_PROC_FS) || defined(HAVE_GREGSET_T)
|
||||
#include <sys/procfs.h>
|
||||
|
||||
/* Prototypes for supply_gregset etc. */
|
||||
#include "gregset.h"
|
||||
|
||||
/*
|
||||
* See the comment in m68k-tdep.c regarding the utility of these functions.
|
||||
*/
|
||||
|
||||
void
|
||||
supply_gregset (gdb_gregset_t *gregsetp)
|
||||
{
|
||||
register int regi;
|
||||
register long *regp = ALPHA_REGSET_BASE (gregsetp);
|
||||
static char zerobuf[MAX_REGISTER_RAW_SIZE] =
|
||||
{0};
|
||||
|
||||
for (regi = 0; regi < 31; regi++)
|
||||
supply_register (regi, (char *) (regp + regi));
|
||||
|
||||
supply_register (PC_REGNUM, (char *) (regp + 31));
|
||||
|
||||
/* Fill inaccessible registers with zero. */
|
||||
supply_register (ZERO_REGNUM, zerobuf);
|
||||
supply_register (FP_REGNUM, zerobuf);
|
||||
}
|
||||
|
||||
void
|
||||
fill_gregset (gdb_gregset_t *gregsetp, int regno)
|
||||
{
|
||||
int regi;
|
||||
register long *regp = ALPHA_REGSET_BASE (gregsetp);
|
||||
|
||||
for (regi = 0; regi < 31; regi++)
|
||||
if ((regno == -1) || (regno == regi))
|
||||
*(regp + regi) = *(long *) ®isters[REGISTER_BYTE (regi)];
|
||||
|
||||
if ((regno == -1) || (regno == PC_REGNUM))
|
||||
*(regp + 31) = *(long *) ®isters[REGISTER_BYTE (PC_REGNUM)];
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we do the same thing for floating-point registers.
|
||||
* Again, see the comments in m68k-tdep.c.
|
||||
*/
|
||||
|
||||
void
|
||||
supply_fpregset (gdb_fpregset_t *fpregsetp)
|
||||
{
|
||||
register int regi;
|
||||
register long *regp = ALPHA_REGSET_BASE (fpregsetp);
|
||||
|
||||
for (regi = 0; regi < 32; regi++)
|
||||
supply_register (regi + FP0_REGNUM, (char *) (regp + regi));
|
||||
}
|
||||
|
||||
void
|
||||
fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
|
||||
{
|
||||
int regi;
|
||||
register long *regp = ALPHA_REGSET_BASE (fpregsetp);
|
||||
|
||||
for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
|
||||
{
|
||||
if ((regno == -1) || (regno == regi))
|
||||
{
|
||||
*(regp + regi - FP0_REGNUM) =
|
||||
*(long *) ®isters[REGISTER_BYTE (regi)];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Register that we are able to handle alpha core file formats. */
|
||||
|
||||
static struct core_fns alpha_osf_core_fns =
|
||||
{
|
||||
/* This really is bfd_target_unknown_flavour. */
|
||||
|
||||
bfd_target_unknown_flavour, /* core_flavour */
|
||||
default_check_format, /* check_format */
|
||||
default_core_sniffer, /* core_sniffer */
|
||||
fetch_osf_core_registers, /* core_read_registers */
|
||||
NULL /* next */
|
||||
};
|
||||
|
||||
static struct core_fns alpha_elf_core_fns =
|
||||
{
|
||||
bfd_target_elf_flavour, /* core_flavour */
|
||||
default_check_format, /* check_format */
|
||||
default_core_sniffer, /* core_sniffer */
|
||||
fetch_elf_core_registers, /* core_read_registers */
|
||||
NULL /* next */
|
||||
};
|
||||
|
||||
void
|
||||
_initialize_core_alpha (void)
|
||||
{
|
||||
add_core_fns (&alpha_osf_core_fns);
|
||||
add_core_fns (&alpha_elf_core_fns);
|
||||
}
|
||||
1691
gdb/alpha-tdep.c
1691
gdb/alpha-tdep.c
File diff suppressed because it is too large
Load Diff
@@ -1,211 +0,0 @@
|
||||
/* Native-dependent code for Alpha BSD's.
|
||||
Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
#include "regcache.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <machine/reg.h>
|
||||
|
||||
#ifdef HAVE_SYS_PROCFS_H
|
||||
#include <sys/procfs.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GREGSET_T
|
||||
typedef struct reg gregset_t;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FPREGSET_T
|
||||
typedef struct fpreg fpregset_t;
|
||||
#endif
|
||||
|
||||
#include "gregset.h"
|
||||
|
||||
/* Number of general-purpose registers. */
|
||||
#define NUM_GREGS 32
|
||||
|
||||
/* Number of floating point registers. */
|
||||
#define NUM_FPREGS 31
|
||||
|
||||
|
||||
/* Transfering the registers between GDB, inferiors and core files. */
|
||||
|
||||
/* Fill GDB's register array with the general-purpose register values
|
||||
in *GREGSETP. */
|
||||
|
||||
void
|
||||
supply_gregset (gregset_t *gregsetp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_GREGS; i++)
|
||||
{
|
||||
if (CANNOT_FETCH_REGISTER (i))
|
||||
supply_register (i, NULL);
|
||||
else
|
||||
supply_register (i, (char *) &gregsetp->r_regs[i]);
|
||||
}
|
||||
|
||||
/* The PC travels in the R_ZERO slot. */
|
||||
supply_register (PC_REGNUM, (char *) &gregsetp->r_regs[R_ZERO]);
|
||||
}
|
||||
|
||||
/* Fill register REGNO (if it is a general-purpose register) in
|
||||
*GREGSETPS with the value in GDB's register array. If REGNO is -1,
|
||||
do this for all registers. */
|
||||
|
||||
void
|
||||
fill_gregset (gregset_t *gregsetp, int regno)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_GREGS; i++)
|
||||
if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i))
|
||||
regcache_collect (i, (char *) &gregsetp->r_regs[i]);
|
||||
|
||||
/* The PC travels in the R_ZERO slot. */
|
||||
if (regno == -1 || regno == PC_REGNUM)
|
||||
regcache_collect (PC_REGNUM, (char *) &gregsetp->r_regs[R_ZERO]);
|
||||
}
|
||||
|
||||
/* Fill GDB's register array with the floating-point register values
|
||||
in *FPREGSETP. */
|
||||
|
||||
void
|
||||
supply_fpregset (fpregset_t *fpregsetp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = FP0_REGNUM; i < FP0_REGNUM + NUM_FPREGS; i++)
|
||||
{
|
||||
if (CANNOT_FETCH_REGISTER (i))
|
||||
supply_register (i, NULL);
|
||||
else
|
||||
supply_register (i, (char *) &fpregsetp->fpr_regs[i - FP0_REGNUM]);
|
||||
}
|
||||
|
||||
supply_register (FPCR_REGNUM, (char *) &fpregsetp->fpr_cr);
|
||||
}
|
||||
|
||||
/* Fill register REGNO (if it is a floating-point register) in
|
||||
*FPREGSETP with the value in GDB's register array. If REGNO is -1,
|
||||
do this for all registers. */
|
||||
|
||||
void
|
||||
fill_fpregset (fpregset_t *fpregsetp, int regno)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = FP0_REGNUM; i < FP0_REGNUM + NUM_FPREGS; i++)
|
||||
if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i))
|
||||
regcache_collect (i, (char *) &fpregsetp->fpr_regs[i - FP0_REGNUM]);
|
||||
|
||||
if (regno == -1 || regno == FPCR_REGNUM)
|
||||
regcache_collect (FPCR_REGNUM, (char *) &fpregsetp->fpr_cr);
|
||||
}
|
||||
|
||||
|
||||
/* Determine if PT_GETREGS fetches this register. */
|
||||
|
||||
static int
|
||||
getregs_supplies (int regno)
|
||||
{
|
||||
|
||||
return ((regno >= V0_REGNUM && regno <= ZERO_REGNUM)
|
||||
|| regno >= PC_REGNUM);
|
||||
}
|
||||
|
||||
|
||||
/* Fetch register REGNO from the inferior. If REGNO is -1, do this
|
||||
for all registers (including the floating point registers). */
|
||||
|
||||
void
|
||||
fetch_inferior_registers (int regno)
|
||||
{
|
||||
|
||||
if (regno == -1 || getregs_supplies (regno))
|
||||
{
|
||||
gregset_t gregs;
|
||||
|
||||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &gregs, 0) == -1)
|
||||
perror_with_name ("Couldn't get registers");
|
||||
|
||||
supply_gregset (&gregs);
|
||||
if (regno != -1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (regno == -1 || regno >= FP0_REGNUM)
|
||||
{
|
||||
fpregset_t fpregs;
|
||||
|
||||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
|
||||
perror_with_name ("Couldn't get floating point status");
|
||||
|
||||
supply_fpregset (&fpregs);
|
||||
}
|
||||
|
||||
/* Reset virtual frame pointer. */
|
||||
supply_register (FP_REGNUM, NULL);
|
||||
}
|
||||
|
||||
/* Store register REGNO back into the inferior. If REGNO is -1, do
|
||||
this for all registers (including the floating point registers). */
|
||||
|
||||
void
|
||||
store_inferior_registers (int regno)
|
||||
{
|
||||
|
||||
if (regno == -1 || getregs_supplies (regno))
|
||||
{
|
||||
gregset_t gregs;
|
||||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &gregs, 0) == -1)
|
||||
perror_with_name ("Couldn't get registers");
|
||||
|
||||
fill_gregset (&gregs, regno);
|
||||
|
||||
if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &gregs, 0) == -1)
|
||||
perror_with_name ("Couldn't write registers");
|
||||
|
||||
if (regno != -1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (regno == -1 || regno >= FP0_REGNUM)
|
||||
{
|
||||
fpregset_t fpregs;
|
||||
|
||||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
|
||||
perror_with_name ("Couldn't get floating point status");
|
||||
|
||||
fill_fpregset (&fpregs, regno);
|
||||
|
||||
if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
|
||||
perror_with_name ("Couldn't write floating point status");
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/* Target-dependent code for FreeBSD/Alpha.
|
||||
Copyright 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "value.h"
|
||||
|
||||
int
|
||||
alphafbsd_use_struct_convention (int gcc_p, struct type *type)
|
||||
{
|
||||
enum type_code code;
|
||||
int i;
|
||||
|
||||
/* All aggregate types that won't fit in a register must be returned
|
||||
in memory. */
|
||||
if (TYPE_LENGTH (type) > REGISTER_SIZE)
|
||||
return 1;
|
||||
|
||||
/* The only aggregate types that can be returned in a register are
|
||||
structs and unions. Arrays must be returned in memory. */
|
||||
code = TYPE_CODE (type);
|
||||
if (code != TYPE_CODE_STRUCT && code != TYPE_CODE_UNION)
|
||||
return 1;
|
||||
|
||||
/* We need to check if this struct/union is "integer" like. For
|
||||
this to be true, the offset of each adressable subfield must be
|
||||
zero. Note that bit fields are not addressable. */
|
||||
for (i = 0; i < TYPE_NFIELDS (type); i++)
|
||||
{
|
||||
/* If the field bitsize is non-zero, it isn't adressable. */
|
||||
if (TYPE_FIELD_BITPOS (type, i) != 0
|
||||
&& TYPE_FIELD_BITSIZE (type, i) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
585
gdb/annotate.c
585
gdb/annotate.c
@@ -1,585 +0,0 @@
|
||||
/* Annotation routines for GDB.
|
||||
Copyright 1986, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1998, 1999,
|
||||
2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "annotate.h"
|
||||
#include "value.h"
|
||||
#include "target.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "breakpoint.h"
|
||||
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
|
||||
extern void _initialize_annotate (void);
|
||||
|
||||
static void print_value_flags (struct type *);
|
||||
|
||||
static void breakpoint_changed (struct breakpoint *);
|
||||
|
||||
void (*annotate_starting_hook) (void);
|
||||
void (*annotate_stopped_hook) (void);
|
||||
void (*annotate_signalled_hook) (void);
|
||||
void (*annotate_signal_hook) (void);
|
||||
void (*annotate_exited_hook) (void);
|
||||
|
||||
static int ignore_count_changed = 0;
|
||||
|
||||
static void
|
||||
print_value_flags (struct type *t)
|
||||
{
|
||||
if (can_dereference (t))
|
||||
printf_filtered ("*");
|
||||
else
|
||||
printf_filtered ("-");
|
||||
}
|
||||
|
||||
void
|
||||
breakpoints_changed (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
target_terminal_ours ();
|
||||
printf_unfiltered ("\n\032\032breakpoints-invalid\n");
|
||||
if (ignore_count_changed)
|
||||
ignore_count_changed = 0; /* Avoid multiple break annotations. */
|
||||
}
|
||||
}
|
||||
|
||||
/* The GUI needs to be informed of ignore_count changes, but we don't
|
||||
want to provide successive multiple breakpoints-invalid messages
|
||||
that are all caused by the fact that the ignore count is changing
|
||||
(which could keep the GUI very busy). One is enough, after the
|
||||
target actually "stops". */
|
||||
|
||||
void
|
||||
annotate_ignore_count_change (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
ignore_count_changed = 1;
|
||||
}
|
||||
|
||||
void
|
||||
annotate_breakpoint (int num)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032breakpoint %d\n", num);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_catchpoint (int num)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032catchpoint %d\n", num);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_watchpoint (int num)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032watchpoint %d\n", num);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_starting (void)
|
||||
{
|
||||
|
||||
if (annotate_starting_hook)
|
||||
annotate_starting_hook ();
|
||||
else
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
printf_filtered ("\n\032\032starting\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_stopped (void)
|
||||
{
|
||||
if (annotate_stopped_hook)
|
||||
annotate_stopped_hook ();
|
||||
else
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032stopped\n");
|
||||
}
|
||||
if (annotation_level > 1 && ignore_count_changed)
|
||||
{
|
||||
ignore_count_changed = 0;
|
||||
breakpoints_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_exited (int exitstatus)
|
||||
{
|
||||
if (annotate_exited_hook)
|
||||
annotate_exited_hook ();
|
||||
else
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032exited %d\n", exitstatus);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signalled (void)
|
||||
{
|
||||
if (annotate_signalled_hook)
|
||||
annotate_signalled_hook ();
|
||||
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032signalled\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_name (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032signal-name\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_name_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032signal-name-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_string (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032signal-string\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_string_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032signal-string-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal (void)
|
||||
{
|
||||
if (annotate_signal_hook)
|
||||
annotate_signal_hook ();
|
||||
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032signal\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_breakpoints_headers (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032breakpoints-headers\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field (int num)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032field %d\n", num);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_breakpoints_table (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032breakpoints-table\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_record (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032record\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_breakpoints_table_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032breakpoints-table-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frames_invalid (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
target_terminal_ours ();
|
||||
printf_unfiltered ("\n\032\032frames-invalid\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field_begin (struct type *type)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
printf_filtered ("\n\032\032field-begin ");
|
||||
print_value_flags (type);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field_name_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032field-name-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field_value (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032field-value\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032field-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_quit (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032quit\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_error (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032error\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_error_begin (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
fprintf_filtered (gdb_stderr, "\n\032\032error-begin\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_history_begin (int histindex, struct type *type)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
printf_filtered ("\n\032\032value-history-begin %d ", histindex);
|
||||
print_value_flags (type);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_begin (struct type *type)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
printf_filtered ("\n\032\032value-begin ");
|
||||
print_value_flags (type);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_history_value (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032value-history-value\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_history_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032value-history-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032value-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_begin (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032display-begin\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_number_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032display-number-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_format (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032display-format\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_expression (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032display-expression\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_expression_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032display-expression-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_value (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032display-value\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032display-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_arg_begin (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032arg-begin\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_arg_name_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032arg-name-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_arg_value (struct type *type)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
printf_filtered ("\n\032\032arg-value ");
|
||||
print_value_flags (type);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_arg_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032arg-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_source (char *filename, int line, int character, int mid, CORE_ADDR pc)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032source ");
|
||||
else
|
||||
printf_filtered ("\032\032");
|
||||
|
||||
printf_filtered ("%s:%d:%d:%s:0x", filename,
|
||||
line, character,
|
||||
mid ? "middle" : "beg");
|
||||
print_address_numeric (pc, 0, gdb_stdout);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_begin (int level, CORE_ADDR pc)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
printf_filtered ("\n\032\032frame-begin %d 0x", level);
|
||||
print_address_numeric (pc, 0, gdb_stdout);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_function_call (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032function-call\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_handler_caller (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032signal-handler-caller\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_address (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-address\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_address_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-address-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_function_name (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-function-name\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_args (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-args\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_begin (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-source-begin\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_file (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-source-file\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_file_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-source-file-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_line (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-source-line\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-source-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_where (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-where\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032frame-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_array_section_begin (int index, struct type *elttype)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
printf_filtered ("\n\032\032array-section-begin %d ", index);
|
||||
print_value_flags (elttype);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_elt_rep (unsigned int repcount)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032elt-rep %u\n", repcount);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_elt_rep_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032elt-rep-end\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_elt (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032elt\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_array_section_end (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered ("\n\032\032array-section-end\n");
|
||||
}
|
||||
|
||||
static void
|
||||
breakpoint_changed (struct breakpoint *b)
|
||||
{
|
||||
breakpoints_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_annotate (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
delete_breakpoint_hook = breakpoint_changed;
|
||||
modify_breakpoint_hook = breakpoint_changed;
|
||||
}
|
||||
}
|
||||
106
gdb/annotate.h
106
gdb/annotate.h
@@ -1,106 +0,0 @@
|
||||
/* Annotation routines for GDB.
|
||||
Copyright 1986, 1989, 1990, 1991, 1992, 1994, 1998, 1999, 2000
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
|
||||
extern void breakpoints_changed (void);
|
||||
|
||||
extern void annotate_ignore_count_change (void);
|
||||
extern void annotate_breakpoint (int);
|
||||
extern void annotate_catchpoint (int);
|
||||
extern void annotate_watchpoint (int);
|
||||
extern void annotate_starting (void);
|
||||
extern void annotate_stopped (void);
|
||||
extern void annotate_exited (int);
|
||||
extern void annotate_signalled (void);
|
||||
extern void annotate_signal_name (void);
|
||||
extern void annotate_signal_name_end (void);
|
||||
extern void annotate_signal_string (void);
|
||||
extern void annotate_signal_string_end (void);
|
||||
extern void annotate_signal (void);
|
||||
|
||||
extern void annotate_breakpoints_headers (void);
|
||||
extern void annotate_field (int);
|
||||
extern void annotate_breakpoints_table (void);
|
||||
extern void annotate_record (void);
|
||||
extern void annotate_breakpoints_table_end (void);
|
||||
|
||||
extern void annotate_frames_invalid (void);
|
||||
|
||||
struct type;
|
||||
|
||||
extern void annotate_field_begin (struct type *);
|
||||
extern void annotate_field_name_end (void);
|
||||
extern void annotate_field_value (void);
|
||||
extern void annotate_field_end (void);
|
||||
|
||||
extern void annotate_quit (void);
|
||||
extern void annotate_error (void);
|
||||
extern void annotate_error_begin (void);
|
||||
|
||||
extern void annotate_value_history_begin (int, struct type *);
|
||||
extern void annotate_value_begin (struct type *);
|
||||
extern void annotate_value_history_value (void);
|
||||
extern void annotate_value_history_end (void);
|
||||
extern void annotate_value_end (void);
|
||||
|
||||
extern void annotate_display_begin (void);
|
||||
extern void annotate_display_number_end (void);
|
||||
extern void annotate_display_format (void);
|
||||
extern void annotate_display_expression (void);
|
||||
extern void annotate_display_expression_end (void);
|
||||
extern void annotate_display_value (void);
|
||||
extern void annotate_display_end (void);
|
||||
|
||||
extern void annotate_arg_begin (void);
|
||||
extern void annotate_arg_name_end (void);
|
||||
extern void annotate_arg_value (struct type *);
|
||||
extern void annotate_arg_end (void);
|
||||
|
||||
extern void annotate_source (char *, int, int, int, CORE_ADDR);
|
||||
|
||||
extern void annotate_frame_begin (int, CORE_ADDR);
|
||||
extern void annotate_function_call (void);
|
||||
extern void annotate_signal_handler_caller (void);
|
||||
extern void annotate_frame_address (void);
|
||||
extern void annotate_frame_address_end (void);
|
||||
extern void annotate_frame_function_name (void);
|
||||
extern void annotate_frame_args (void);
|
||||
extern void annotate_frame_source_begin (void);
|
||||
extern void annotate_frame_source_file (void);
|
||||
extern void annotate_frame_source_file_end (void);
|
||||
extern void annotate_frame_source_line (void);
|
||||
extern void annotate_frame_source_end (void);
|
||||
extern void annotate_frame_where (void);
|
||||
extern void annotate_frame_end (void);
|
||||
|
||||
extern void annotate_array_section_begin (int, struct type *);
|
||||
extern void annotate_elt_rep (unsigned int);
|
||||
extern void annotate_elt_rep_end (void);
|
||||
extern void annotate_elt (void);
|
||||
extern void annotate_array_section_end (void);
|
||||
|
||||
extern void (*annotate_starting_hook) (void);
|
||||
extern void (*annotate_stopped_hook) (void);
|
||||
extern void (*annotate_signalled_hook) (void);
|
||||
extern void (*annotate_signal_hook) (void);
|
||||
extern void (*annotate_exited_hook) (void);
|
||||
727
gdb/arc-tdep.c
727
gdb/arc-tdep.c
@@ -1,727 +0,0 @@
|
||||
/* ARC target-dependent stuff.
|
||||
Copyright 1995, 1996, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
#include "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "floatformat.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "regcache.h"
|
||||
|
||||
/* Local functions */
|
||||
|
||||
static int arc_set_cpu_type (char *str);
|
||||
|
||||
/* Current CPU, set with the "set cpu" command. */
|
||||
static int arc_bfd_mach_type;
|
||||
char *arc_cpu_type;
|
||||
char *tmp_arc_cpu_type;
|
||||
|
||||
/* Table of cpu names. */
|
||||
struct
|
||||
{
|
||||
char *name;
|
||||
int value;
|
||||
}
|
||||
arc_cpu_type_table[] =
|
||||
{
|
||||
{ "arc5", bfd_mach_arc_5 },
|
||||
{ "arc6", bfd_mach_arc_6 },
|
||||
{ "arc7", bfd_mach_arc_7 },
|
||||
{ "arc8", bfd_mach_arc_8 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/* Used by simulator. */
|
||||
int display_pipeline_p;
|
||||
int cpu_timer;
|
||||
/* This one must have the same type as used in the emulator.
|
||||
It's currently an enum so this should be ok for now. */
|
||||
int debug_pipeline_p;
|
||||
|
||||
#define ARC_CALL_SAVED_REG(r) ((r) >= 16 && (r) < 24)
|
||||
|
||||
#define OPMASK 0xf8000000
|
||||
|
||||
/* Instruction field accessor macros.
|
||||
See the Programmer's Reference Manual. */
|
||||
#define X_OP(i) (((i) >> 27) & 0x1f)
|
||||
#define X_A(i) (((i) >> 21) & 0x3f)
|
||||
#define X_B(i) (((i) >> 15) & 0x3f)
|
||||
#define X_C(i) (((i) >> 9) & 0x3f)
|
||||
#define X_D(i) ((((i) & 0x1ff) ^ 0x100) - 0x100)
|
||||
#define X_L(i) (((((i) >> 5) & 0x3ffffc) ^ 0x200000) - 0x200000)
|
||||
#define X_N(i) (((i) >> 5) & 3)
|
||||
#define X_Q(i) ((i) & 0x1f)
|
||||
|
||||
/* Return non-zero if X is a short immediate data indicator. */
|
||||
#define SHIMM_P(x) ((x) == 61 || (x) == 63)
|
||||
|
||||
/* Return non-zero if X is a "long" (32 bit) immediate data indicator. */
|
||||
#define LIMM_P(x) ((x) == 62)
|
||||
|
||||
/* Build a simple instruction. */
|
||||
#define BUILD_INSN(op, a, b, c, d) \
|
||||
((((op) & 31) << 27) \
|
||||
| (((a) & 63) << 21) \
|
||||
| (((b) & 63) << 15) \
|
||||
| (((c) & 63) << 9) \
|
||||
| ((d) & 511))
|
||||
|
||||
/* Codestream stuff. */
|
||||
static void codestream_read (unsigned int *, int);
|
||||
static void codestream_seek (CORE_ADDR);
|
||||
static unsigned int codestream_fill (int);
|
||||
|
||||
#define CODESTREAM_BUFSIZ 16
|
||||
static CORE_ADDR codestream_next_addr;
|
||||
static CORE_ADDR codestream_addr;
|
||||
/* FIXME assumes sizeof (int) == 32? */
|
||||
static unsigned int codestream_buf[CODESTREAM_BUFSIZ];
|
||||
static int codestream_off;
|
||||
static int codestream_cnt;
|
||||
|
||||
#define codestream_tell() \
|
||||
(codestream_addr + codestream_off * sizeof (codestream_buf[0]))
|
||||
#define codestream_peek() \
|
||||
(codestream_cnt == 0 \
|
||||
? codestream_fill (1) \
|
||||
: codestream_buf[codestream_off])
|
||||
#define codestream_get() \
|
||||
(codestream_cnt-- == 0 \
|
||||
? codestream_fill (0) \
|
||||
: codestream_buf[codestream_off++])
|
||||
|
||||
static unsigned int
|
||||
codestream_fill (int peek_flag)
|
||||
{
|
||||
codestream_addr = codestream_next_addr;
|
||||
codestream_next_addr += CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]);
|
||||
codestream_off = 0;
|
||||
codestream_cnt = CODESTREAM_BUFSIZ;
|
||||
read_memory (codestream_addr, (char *) codestream_buf,
|
||||
CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]));
|
||||
/* FIXME: check return code? */
|
||||
|
||||
|
||||
/* Handle byte order differences -> convert to host byte ordering. */
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < CODESTREAM_BUFSIZ; i++)
|
||||
codestream_buf[i] =
|
||||
extract_unsigned_integer (&codestream_buf[i],
|
||||
sizeof (codestream_buf[i]));
|
||||
}
|
||||
|
||||
if (peek_flag)
|
||||
return codestream_peek ();
|
||||
else
|
||||
return codestream_get ();
|
||||
}
|
||||
|
||||
static void
|
||||
codestream_seek (CORE_ADDR place)
|
||||
{
|
||||
codestream_next_addr = place / CODESTREAM_BUFSIZ;
|
||||
codestream_next_addr *= CODESTREAM_BUFSIZ;
|
||||
codestream_cnt = 0;
|
||||
codestream_fill (1);
|
||||
while (codestream_tell () != place)
|
||||
codestream_get ();
|
||||
}
|
||||
|
||||
/* This function is currently unused but leave in for now. */
|
||||
|
||||
static void
|
||||
codestream_read (unsigned int *buf, int count)
|
||||
{
|
||||
unsigned int *p;
|
||||
int i;
|
||||
p = buf;
|
||||
for (i = 0; i < count; i++)
|
||||
*p++ = codestream_get ();
|
||||
}
|
||||
|
||||
/* Set up prologue scanning and return the first insn. */
|
||||
|
||||
static unsigned int
|
||||
setup_prologue_scan (CORE_ADDR pc)
|
||||
{
|
||||
unsigned int insn;
|
||||
|
||||
codestream_seek (pc);
|
||||
insn = codestream_get ();
|
||||
|
||||
return insn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find & return amount a local space allocated, and advance codestream to
|
||||
* first register push (if any).
|
||||
* If entry sequence doesn't make sense, return -1, and leave
|
||||
* codestream pointer random.
|
||||
*/
|
||||
|
||||
static long
|
||||
arc_get_frame_setup (CORE_ADDR pc)
|
||||
{
|
||||
unsigned int insn;
|
||||
/* Size of frame or -1 if unrecognizable prologue. */
|
||||
int frame_size = -1;
|
||||
/* An initial "sub sp,sp,N" may or may not be for a stdarg fn. */
|
||||
int maybe_stdarg_decr = -1;
|
||||
|
||||
insn = setup_prologue_scan (pc);
|
||||
|
||||
/* The authority for what appears here is the home-grown ABI.
|
||||
The most recent version is 1.2. */
|
||||
|
||||
/* First insn may be "sub sp,sp,N" if stdarg fn. */
|
||||
if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
|
||||
== BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
|
||||
{
|
||||
maybe_stdarg_decr = X_D (insn);
|
||||
insn = codestream_get ();
|
||||
}
|
||||
|
||||
if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
|
||||
== BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
|
||||
{
|
||||
insn = codestream_get ();
|
||||
/* Frame may not be necessary, even though blink is saved.
|
||||
At least this is something we recognize. */
|
||||
frame_size = 0;
|
||||
}
|
||||
|
||||
if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st fp,[sp] */
|
||||
== BUILD_INSN (2, 0, SP_REGNUM, FP_REGNUM, 0))
|
||||
{
|
||||
insn = codestream_get ();
|
||||
if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
|
||||
!= BUILD_INSN (12, FP_REGNUM, SP_REGNUM, SP_REGNUM, 0))
|
||||
return -1;
|
||||
|
||||
/* Check for stack adjustment sub sp,sp,N. */
|
||||
insn = codestream_peek ();
|
||||
if ((insn & BUILD_INSN (-1, -1, -1, 0, 0))
|
||||
== BUILD_INSN (10, SP_REGNUM, SP_REGNUM, 0, 0))
|
||||
{
|
||||
if (LIMM_P (X_C (insn)))
|
||||
frame_size = codestream_get ();
|
||||
else if (SHIMM_P (X_C (insn)))
|
||||
frame_size = X_D (insn);
|
||||
else
|
||||
return -1;
|
||||
if (frame_size < 0)
|
||||
return -1;
|
||||
|
||||
codestream_get ();
|
||||
|
||||
/* This sequence is used to get the address of the return
|
||||
buffer for a function that returns a structure. */
|
||||
insn = codestream_peek ();
|
||||
if ((insn & OPMASK) == 0x60000000)
|
||||
codestream_get ();
|
||||
}
|
||||
/* Frameless fn. */
|
||||
else
|
||||
{
|
||||
frame_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we found a "sub sp,sp,N" and nothing else, it may or may not be a
|
||||
stdarg fn. The stdarg decrement is not treated as part of the frame size,
|
||||
so we have a dilemma: what do we return? For now, if we get a
|
||||
"sub sp,sp,N" and nothing else assume this isn't a stdarg fn. One way
|
||||
to fix this completely would be to add a bit to the function descriptor
|
||||
that says the function is a stdarg function. */
|
||||
|
||||
if (frame_size < 0 && maybe_stdarg_decr > 0)
|
||||
return maybe_stdarg_decr;
|
||||
return frame_size;
|
||||
}
|
||||
|
||||
/* Given a pc value, skip it forward past the function prologue by
|
||||
disassembling instructions that appear to be a prologue.
|
||||
|
||||
If FRAMELESS_P is set, we are only testing to see if the function
|
||||
is frameless. If it is a frameless function, return PC unchanged.
|
||||
This allows a quicker answer. */
|
||||
|
||||
CORE_ADDR
|
||||
arc_skip_prologue (CORE_ADDR pc, int frameless_p)
|
||||
{
|
||||
unsigned int insn;
|
||||
int i, frame_size;
|
||||
|
||||
if ((frame_size = arc_get_frame_setup (pc)) < 0)
|
||||
return (pc);
|
||||
|
||||
if (frameless_p)
|
||||
return frame_size == 0 ? pc : codestream_tell ();
|
||||
|
||||
/* Skip over register saves. */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
insn = codestream_peek ();
|
||||
if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
|
||||
!= BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
|
||||
break; /* not st insn */
|
||||
if (!ARC_CALL_SAVED_REG (X_C (insn)))
|
||||
break;
|
||||
codestream_get ();
|
||||
}
|
||||
|
||||
return codestream_tell ();
|
||||
}
|
||||
|
||||
/* Return the return address for a frame.
|
||||
This is used to implement FRAME_SAVED_PC.
|
||||
This is taken from frameless_look_for_prologue. */
|
||||
|
||||
CORE_ADDR
|
||||
arc_frame_saved_pc (struct frame_info *frame)
|
||||
{
|
||||
CORE_ADDR func_start;
|
||||
unsigned int insn;
|
||||
|
||||
func_start = get_pc_function_start (frame->pc) + FUNCTION_START_OFFSET;
|
||||
if (func_start == 0)
|
||||
{
|
||||
/* Best guess. */
|
||||
return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
|
||||
}
|
||||
|
||||
/* The authority for what appears here is the home-grown ABI.
|
||||
The most recent version is 1.2. */
|
||||
|
||||
insn = setup_prologue_scan (func_start);
|
||||
|
||||
/* First insn may be "sub sp,sp,N" if stdarg fn. */
|
||||
if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
|
||||
== BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
|
||||
insn = codestream_get ();
|
||||
|
||||
/* If the next insn is "st blink,[sp,4]" we can get blink from there.
|
||||
Otherwise this is a leaf function and we can use blink. Note that
|
||||
this still allows for the case where a leaf function saves/clobbers/
|
||||
restores blink. */
|
||||
|
||||
if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
|
||||
!= BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
|
||||
return ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM));
|
||||
else
|
||||
return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the first few instructions of the function to see
|
||||
* what registers were stored.
|
||||
*
|
||||
* The startup sequence can be at the start of the function.
|
||||
* 'st blink,[sp+4], st fp,[sp], mov fp,sp'
|
||||
*
|
||||
* Local space is allocated just below by sub sp,sp,nnn.
|
||||
* Next, the registers used by this function are stored (as offsets from sp).
|
||||
*/
|
||||
|
||||
void
|
||||
frame_find_saved_regs (struct frame_info *fip, struct frame_saved_regs *fsrp)
|
||||
{
|
||||
long locals;
|
||||
unsigned int insn;
|
||||
CORE_ADDR dummy_bottom;
|
||||
CORE_ADDR adr;
|
||||
int i, regnum, offset;
|
||||
|
||||
memset (fsrp, 0, sizeof *fsrp);
|
||||
|
||||
/* If frame is the end of a dummy, compute where the beginning would be. */
|
||||
dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH;
|
||||
|
||||
/* Check if the PC is in the stack, in a dummy frame. */
|
||||
if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
|
||||
{
|
||||
/* all regs were saved by push_call_dummy () */
|
||||
adr = fip->frame;
|
||||
for (i = 0; i < NUM_REGS; i++)
|
||||
{
|
||||
adr -= REGISTER_RAW_SIZE (i);
|
||||
fsrp->regs[i] = adr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
locals = arc_get_frame_setup (get_pc_function_start (fip->pc));
|
||||
|
||||
if (locals >= 0)
|
||||
{
|
||||
/* Set `adr' to the value of `sp'. */
|
||||
adr = fip->frame - locals;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
insn = codestream_get ();
|
||||
if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
|
||||
!= BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
|
||||
break;
|
||||
regnum = X_C (insn);
|
||||
offset = X_D (insn);
|
||||
fsrp->regs[regnum] = adr + offset;
|
||||
}
|
||||
}
|
||||
|
||||
fsrp->regs[PC_REGNUM] = fip->frame + 4;
|
||||
fsrp->regs[FP_REGNUM] = fip->frame;
|
||||
}
|
||||
|
||||
void
|
||||
arc_push_dummy_frame (void)
|
||||
{
|
||||
CORE_ADDR sp = read_register (SP_REGNUM);
|
||||
int regnum;
|
||||
char regbuf[MAX_REGISTER_RAW_SIZE];
|
||||
|
||||
read_register_gen (PC_REGNUM, regbuf);
|
||||
write_memory (sp + 4, regbuf, REGISTER_SIZE);
|
||||
read_register_gen (FP_REGNUM, regbuf);
|
||||
write_memory (sp, regbuf, REGISTER_SIZE);
|
||||
write_register (FP_REGNUM, sp);
|
||||
for (regnum = 0; regnum < NUM_REGS; regnum++)
|
||||
{
|
||||
read_register_gen (regnum, regbuf);
|
||||
sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum));
|
||||
}
|
||||
sp += (2 * REGISTER_SIZE);
|
||||
write_register (SP_REGNUM, sp);
|
||||
}
|
||||
|
||||
void
|
||||
arc_pop_frame (void)
|
||||
{
|
||||
struct frame_info *frame = get_current_frame ();
|
||||
CORE_ADDR fp;
|
||||
int regnum;
|
||||
struct frame_saved_regs fsr;
|
||||
char regbuf[MAX_REGISTER_RAW_SIZE];
|
||||
|
||||
fp = FRAME_FP (frame);
|
||||
get_frame_saved_regs (frame, &fsr);
|
||||
for (regnum = 0; regnum < NUM_REGS; regnum++)
|
||||
{
|
||||
CORE_ADDR adr;
|
||||
adr = fsr.regs[regnum];
|
||||
if (adr)
|
||||
{
|
||||
read_memory (adr, regbuf, REGISTER_RAW_SIZE (regnum));
|
||||
write_register_bytes (REGISTER_BYTE (regnum), regbuf,
|
||||
REGISTER_RAW_SIZE (regnum));
|
||||
}
|
||||
}
|
||||
write_register (FP_REGNUM, read_memory_integer (fp, 4));
|
||||
write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
|
||||
write_register (SP_REGNUM, fp + 8);
|
||||
flush_cached_frames ();
|
||||
}
|
||||
|
||||
/* Simulate single-step. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NORMAL4, /* a normal 4 byte insn */
|
||||
NORMAL8, /* a normal 8 byte insn */
|
||||
BRANCH4, /* a 4 byte branch insn, including ones without delay slots */
|
||||
BRANCH8, /* an 8 byte branch insn, including ones with delay slots */
|
||||
}
|
||||
insn_type;
|
||||
|
||||
/* Return the type of INSN and store in TARGET the destination address of a
|
||||
branch if this is one. */
|
||||
/* ??? Need to verify all cases are properly handled. */
|
||||
|
||||
static insn_type
|
||||
get_insn_type (unsigned long insn, CORE_ADDR pc, CORE_ADDR *target)
|
||||
{
|
||||
unsigned long limm;
|
||||
|
||||
switch (insn >> 27)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2: /* load/store insns */
|
||||
if (LIMM_P (X_A (insn))
|
||||
|| LIMM_P (X_B (insn))
|
||||
|| LIMM_P (X_C (insn)))
|
||||
return NORMAL8;
|
||||
return NORMAL4;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6: /* branch insns */
|
||||
*target = pc + 4 + X_L (insn);
|
||||
/* ??? It isn't clear that this is always the right answer.
|
||||
The problem occurs when the next insn is an 8 byte insn. If the
|
||||
branch is conditional there's no worry as there shouldn't be an 8
|
||||
byte insn following. The programmer may be cheating if s/he knows
|
||||
the branch will never be taken, but we don't deal with that.
|
||||
Note that the programmer is also allowed to play games by putting
|
||||
an insn with long immediate data in the delay slot and then duplicate
|
||||
the long immediate data at the branch target. Ugh! */
|
||||
if (X_N (insn) == 0)
|
||||
return BRANCH4;
|
||||
return BRANCH8;
|
||||
case 7: /* jump insns */
|
||||
if (LIMM_P (X_B (insn)))
|
||||
{
|
||||
limm = read_memory_integer (pc + 4, 4);
|
||||
*target = ARC_PC_TO_REAL_ADDRESS (limm);
|
||||
return BRANCH8;
|
||||
}
|
||||
if (SHIMM_P (X_B (insn)))
|
||||
*target = ARC_PC_TO_REAL_ADDRESS (X_D (insn));
|
||||
else
|
||||
*target = ARC_PC_TO_REAL_ADDRESS (read_register (X_B (insn)));
|
||||
if (X_Q (insn) == 0 && X_N (insn) == 0)
|
||||
return BRANCH4;
|
||||
return BRANCH8;
|
||||
default: /* arithmetic insns, etc. */
|
||||
if (LIMM_P (X_A (insn))
|
||||
|| LIMM_P (X_B (insn))
|
||||
|| LIMM_P (X_C (insn)))
|
||||
return NORMAL8;
|
||||
return NORMAL4;
|
||||
}
|
||||
}
|
||||
|
||||
/* single_step() is called just before we want to resume the inferior, if we
|
||||
want to single-step it but there is no hardware or kernel single-step
|
||||
support. We find all the possible targets of the coming instruction and
|
||||
breakpoint them.
|
||||
|
||||
single_step is also called just after the inferior stops. If we had
|
||||
set up a simulated single-step, we undo our damage. */
|
||||
|
||||
void
|
||||
arc_software_single_step (enum target_signal ignore, /* sig but we don't need it */
|
||||
int insert_breakpoints_p)
|
||||
{
|
||||
static CORE_ADDR next_pc, target;
|
||||
static int brktrg_p;
|
||||
typedef char binsn_quantum[BREAKPOINT_MAX];
|
||||
static binsn_quantum break_mem[2];
|
||||
|
||||
if (insert_breakpoints_p)
|
||||
{
|
||||
insn_type type;
|
||||
CORE_ADDR pc;
|
||||
unsigned long insn;
|
||||
|
||||
pc = read_register (PC_REGNUM);
|
||||
insn = read_memory_integer (pc, 4);
|
||||
type = get_insn_type (insn, pc, &target);
|
||||
|
||||
/* Always set a breakpoint for the insn after the branch. */
|
||||
next_pc = pc + ((type == NORMAL8 || type == BRANCH8) ? 8 : 4);
|
||||
target_insert_breakpoint (next_pc, break_mem[0]);
|
||||
|
||||
brktrg_p = 0;
|
||||
|
||||
if ((type == BRANCH4 || type == BRANCH8)
|
||||
/* Watch out for branches to the following location.
|
||||
We just stored a breakpoint there and another call to
|
||||
target_insert_breakpoint will think the real insn is the
|
||||
breakpoint we just stored there. */
|
||||
&& target != next_pc)
|
||||
{
|
||||
brktrg_p = 1;
|
||||
target_insert_breakpoint (target, break_mem[1]);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove breakpoints. */
|
||||
target_remove_breakpoint (next_pc, break_mem[0]);
|
||||
|
||||
if (brktrg_p)
|
||||
target_remove_breakpoint (target, break_mem[1]);
|
||||
|
||||
/* Fix the pc. */
|
||||
stop_pc -= DECR_PC_AFTER_BREAK;
|
||||
write_pc (stop_pc);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GET_LONGJMP_TARGET
|
||||
/* Figure out where the longjmp will land. Slurp the args out of the stack.
|
||||
We expect the first arg to be a pointer to the jmp_buf structure from which
|
||||
we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
|
||||
This routine returns true on success. */
|
||||
|
||||
int
|
||||
get_longjmp_target (CORE_ADDR *pc)
|
||||
{
|
||||
char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
|
||||
CORE_ADDR sp, jb_addr;
|
||||
|
||||
sp = read_register (SP_REGNUM);
|
||||
|
||||
if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
|
||||
buf,
|
||||
TARGET_PTR_BIT / TARGET_CHAR_BIT))
|
||||
return 0;
|
||||
|
||||
jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
|
||||
|
||||
if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
|
||||
TARGET_PTR_BIT / TARGET_CHAR_BIT))
|
||||
return 0;
|
||||
|
||||
*pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* GET_LONGJMP_TARGET */
|
||||
|
||||
/* Disassemble one instruction. */
|
||||
|
||||
static int
|
||||
arc_print_insn (bfd_vma vma, disassemble_info *info)
|
||||
{
|
||||
static int current_mach;
|
||||
static int current_endian;
|
||||
static disassembler_ftype current_disasm;
|
||||
|
||||
if (current_disasm == NULL
|
||||
|| arc_bfd_mach_type != current_mach
|
||||
|| TARGET_BYTE_ORDER != current_endian)
|
||||
{
|
||||
current_mach = arc_bfd_mach_type;
|
||||
current_endian = TARGET_BYTE_ORDER;
|
||||
current_disasm = arc_get_disassembler (NULL);
|
||||
}
|
||||
|
||||
return (*current_disasm) (vma, info);
|
||||
}
|
||||
|
||||
/* Command to set cpu type. */
|
||||
|
||||
void
|
||||
arc_set_cpu_type_command (char *args, int from_tty)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tmp_arc_cpu_type == NULL || *tmp_arc_cpu_type == '\0')
|
||||
{
|
||||
printf_unfiltered ("The known ARC cpu types are as follows:\n");
|
||||
for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
|
||||
printf_unfiltered ("%s\n", arc_cpu_type_table[i].name);
|
||||
|
||||
/* Restore the value. */
|
||||
tmp_arc_cpu_type = xstrdup (arc_cpu_type);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!arc_set_cpu_type (tmp_arc_cpu_type))
|
||||
{
|
||||
error ("Unknown cpu type `%s'.", tmp_arc_cpu_type);
|
||||
/* Restore its value. */
|
||||
tmp_arc_cpu_type = xstrdup (arc_cpu_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
arc_show_cpu_type_command (char *args, int from_tty)
|
||||
{
|
||||
}
|
||||
|
||||
/* Modify the actual cpu type.
|
||||
Result is a boolean indicating success. */
|
||||
|
||||
static int
|
||||
arc_set_cpu_type (char *str)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
|
||||
{
|
||||
if (strcasecmp (str, arc_cpu_type_table[i].name) == 0)
|
||||
{
|
||||
arc_cpu_type = str;
|
||||
arc_bfd_mach_type = arc_cpu_type_table[i].value;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_arc_tdep (void)
|
||||
{
|
||||
struct cmd_list_element *c;
|
||||
|
||||
c = add_set_cmd ("cpu", class_support, var_string_noescape,
|
||||
(char *) &tmp_arc_cpu_type,
|
||||
"Set the type of ARC cpu in use.\n\
|
||||
This command has two purposes. In a multi-cpu system it lets one\n\
|
||||
change the cpu being debugged. It also gives one access to\n\
|
||||
cpu-type-specific registers and recognize cpu-type-specific instructions.\
|
||||
",
|
||||
&setlist);
|
||||
set_cmd_cfunc (c, arc_set_cpu_type_command);
|
||||
c = add_show_from_set (c, &showlist);
|
||||
set_cmd_cfunc (c, arc_show_cpu_type_command);
|
||||
|
||||
/* We have to use xstrdup() here because the `set' command frees it
|
||||
before setting a new value. */
|
||||
tmp_arc_cpu_type = xstrdup (DEFAULT_ARC_CPU_TYPE);
|
||||
arc_set_cpu_type (tmp_arc_cpu_type);
|
||||
|
||||
c = add_set_cmd ("displaypipeline", class_support, var_zinteger,
|
||||
(char *) &display_pipeline_p,
|
||||
"Set pipeline display (simulator only).\n\
|
||||
When enabled, the state of the pipeline after each cycle is displayed.",
|
||||
&setlist);
|
||||
c = add_show_from_set (c, &showlist);
|
||||
|
||||
c = add_set_cmd ("debugpipeline", class_support, var_zinteger,
|
||||
(char *) &debug_pipeline_p,
|
||||
"Set pipeline debug display (simulator only).\n\
|
||||
When enabled, debugging information about the pipeline is displayed.",
|
||||
&setlist);
|
||||
c = add_show_from_set (c, &showlist);
|
||||
|
||||
c = add_set_cmd ("cputimer", class_support, var_zinteger,
|
||||
(char *) &cpu_timer,
|
||||
"Set maximum cycle count (simulator only).\n\
|
||||
Control will return to gdb if the timer expires.\n\
|
||||
A negative value disables the timer.",
|
||||
&setlist);
|
||||
c = add_show_from_set (c, &showlist);
|
||||
|
||||
tm_print_insn = arc_print_insn;
|
||||
}
|
||||
861
gdb/arch-utils.c
861
gdb/arch-utils.c
@@ -1,861 +0,0 @@
|
||||
/* Dynamic architecture support for GDB, the GNU debugger.
|
||||
Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#if GDB_MULTI_ARCH
|
||||
#include "arch-utils.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "inferior.h" /* enum CALL_DUMMY_LOCATION et.al. */
|
||||
#else
|
||||
/* Just include everything in sight so that the every old definition
|
||||
of macro is visible. */
|
||||
#include "gdb_string.h"
|
||||
#include "symtab.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
#include "breakpoint.h"
|
||||
#include "gdb_wait.h"
|
||||
#include "gdbcore.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "target.h"
|
||||
#include "annotate.h"
|
||||
#endif
|
||||
#include "regcache.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "floatformat.h"
|
||||
|
||||
/* Use the program counter to determine the contents and size
|
||||
of a breakpoint instruction. If no target-dependent macro
|
||||
BREAKPOINT_FROM_PC has been defined to implement this function,
|
||||
assume that the breakpoint doesn't depend on the PC, and
|
||||
use the values of the BIG_BREAKPOINT and LITTLE_BREAKPOINT macros.
|
||||
Return a pointer to a string of bytes that encode a breakpoint
|
||||
instruction, stores the length of the string to *lenptr,
|
||||
and optionally adjust the pc to point to the correct memory location
|
||||
for inserting the breakpoint. */
|
||||
|
||||
unsigned char *
|
||||
legacy_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
|
||||
{
|
||||
/* {BIG_,LITTLE_}BREAKPOINT is the sequence of bytes we insert for a
|
||||
breakpoint. On some machines, breakpoints are handled by the
|
||||
target environment and we don't have to worry about them here. */
|
||||
#ifdef BIG_BREAKPOINT
|
||||
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
|
||||
{
|
||||
static unsigned char big_break_insn[] = BIG_BREAKPOINT;
|
||||
*lenptr = sizeof (big_break_insn);
|
||||
return big_break_insn;
|
||||
}
|
||||
#endif
|
||||
#ifdef LITTLE_BREAKPOINT
|
||||
if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG)
|
||||
{
|
||||
static unsigned char little_break_insn[] = LITTLE_BREAKPOINT;
|
||||
*lenptr = sizeof (little_break_insn);
|
||||
return little_break_insn;
|
||||
}
|
||||
#endif
|
||||
#ifdef BREAKPOINT
|
||||
{
|
||||
static unsigned char break_insn[] = BREAKPOINT;
|
||||
*lenptr = sizeof (break_insn);
|
||||
return break_insn;
|
||||
}
|
||||
#endif
|
||||
*lenptr = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
generic_frameless_function_invocation_not (struct frame_info *fi)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
generic_return_value_on_stack_not (struct type *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
generic_skip_trampoline_code (CORE_ADDR pc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
generic_in_solib_call_trampoline (CORE_ADDR pc, char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
legacy_register_name (int i)
|
||||
{
|
||||
#ifdef REGISTER_NAMES
|
||||
static char *names[] = REGISTER_NAMES;
|
||||
if (i < 0 || i >= (sizeof (names) / sizeof (*names)))
|
||||
return NULL;
|
||||
else
|
||||
return names[i];
|
||||
#else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"legacy_register_name: called.");
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (CALL_DUMMY)
|
||||
LONGEST legacy_call_dummy_words[] = CALL_DUMMY;
|
||||
#else
|
||||
LONGEST legacy_call_dummy_words[1];
|
||||
#endif
|
||||
int legacy_sizeof_call_dummy_words = sizeof (legacy_call_dummy_words);
|
||||
|
||||
void
|
||||
generic_remote_translate_xfer_address (CORE_ADDR gdb_addr, int gdb_len,
|
||||
CORE_ADDR * rem_addr, int *rem_len)
|
||||
{
|
||||
*rem_addr = gdb_addr;
|
||||
*rem_len = gdb_len;
|
||||
}
|
||||
|
||||
int
|
||||
generic_prologue_frameless_p (CORE_ADDR ip)
|
||||
{
|
||||
#ifdef SKIP_PROLOGUE_FRAMELESS_P
|
||||
return ip == SKIP_PROLOGUE_FRAMELESS_P (ip);
|
||||
#else
|
||||
return ip == SKIP_PROLOGUE (ip);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* New/multi-arched targets should use the correct gdbarch field
|
||||
instead of using this global pointer. */
|
||||
int
|
||||
legacy_print_insn (bfd_vma vma, disassemble_info *info)
|
||||
{
|
||||
return (*tm_print_insn) (vma, info);
|
||||
}
|
||||
|
||||
/* Helper functions for INNER_THAN */
|
||||
|
||||
int
|
||||
core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs)
|
||||
{
|
||||
return (lhs < rhs);
|
||||
}
|
||||
|
||||
int
|
||||
core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs)
|
||||
{
|
||||
return (lhs > rhs);
|
||||
}
|
||||
|
||||
|
||||
/* Helper functions for TARGET_{FLOAT,DOUBLE}_FORMAT */
|
||||
|
||||
const struct floatformat *
|
||||
default_float_format (struct gdbarch *gdbarch)
|
||||
{
|
||||
#if GDB_MULTI_ARCH
|
||||
int byte_order = gdbarch_byte_order (gdbarch);
|
||||
#else
|
||||
int byte_order = TARGET_BYTE_ORDER;
|
||||
#endif
|
||||
switch (byte_order)
|
||||
{
|
||||
case BFD_ENDIAN_BIG:
|
||||
return &floatformat_ieee_single_big;
|
||||
case BFD_ENDIAN_LITTLE:
|
||||
return &floatformat_ieee_single_little;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"default_float_format: bad byte order");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const struct floatformat *
|
||||
default_double_format (struct gdbarch *gdbarch)
|
||||
{
|
||||
#if GDB_MULTI_ARCH
|
||||
int byte_order = gdbarch_byte_order (gdbarch);
|
||||
#else
|
||||
int byte_order = TARGET_BYTE_ORDER;
|
||||
#endif
|
||||
switch (byte_order)
|
||||
{
|
||||
case BFD_ENDIAN_BIG:
|
||||
return &floatformat_ieee_double_big;
|
||||
case BFD_ENDIAN_LITTLE:
|
||||
return &floatformat_ieee_double_little;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"default_double_format: bad byte order");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
default_print_float_info (void)
|
||||
{
|
||||
#ifdef FLOAT_INFO
|
||||
#if GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL
|
||||
#error "FLOAT_INFO defined in multi-arch"
|
||||
#endif
|
||||
FLOAT_INFO;
|
||||
#else
|
||||
printf_filtered ("No floating point info available for this processor.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Misc helper functions for targets. */
|
||||
|
||||
int
|
||||
frame_num_args_unknown (struct frame_info *fi)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
generic_register_convertible_not (int num)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Under some ABI's that specify the `struct convention' for returning
|
||||
structures by value, by the time we've returned from the function,
|
||||
the return value is sitting there in the caller's buffer, but GDB
|
||||
has no way to find the address of that buffer.
|
||||
|
||||
On such architectures, use this function as your
|
||||
extract_struct_value_address method. When asked to a struct
|
||||
returned by value in this fashion, GDB will print a nice error
|
||||
message, instead of garbage. */
|
||||
CORE_ADDR
|
||||
generic_cannot_extract_struct_value_address (char *dummy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
default_register_sim_regno (int num)
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
CORE_ADDR
|
||||
core_addr_identity (CORE_ADDR addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
int
|
||||
no_op_reg_to_regnum (int reg)
|
||||
{
|
||||
return reg;
|
||||
}
|
||||
|
||||
/* For use by frame_args_address and frame_locals_address. */
|
||||
CORE_ADDR
|
||||
default_frame_address (struct frame_info *fi)
|
||||
{
|
||||
return fi->frame;
|
||||
}
|
||||
|
||||
/* Default prepare_to_procced(). */
|
||||
int
|
||||
default_prepare_to_proceed (int select_it)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generic prepare_to_proceed(). This one should be suitable for most
|
||||
targets that support threads. */
|
||||
int
|
||||
generic_prepare_to_proceed (int select_it)
|
||||
{
|
||||
ptid_t wait_ptid;
|
||||
struct target_waitstatus wait_status;
|
||||
|
||||
/* Get the last target status returned by target_wait(). */
|
||||
get_last_target_status (&wait_ptid, &wait_status);
|
||||
|
||||
/* Make sure we were stopped either at a breakpoint, or because
|
||||
of a Ctrl-C. */
|
||||
if (wait_status.kind != TARGET_WAITKIND_STOPPED
|
||||
|| (wait_status.value.sig != TARGET_SIGNAL_TRAP &&
|
||||
wait_status.value.sig != TARGET_SIGNAL_INT))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ptid_equal (wait_ptid, minus_one_ptid)
|
||||
&& !ptid_equal (inferior_ptid, wait_ptid))
|
||||
{
|
||||
/* Switched over from WAIT_PID. */
|
||||
CORE_ADDR wait_pc = read_pc_pid (wait_ptid);
|
||||
|
||||
if (wait_pc != read_pc ())
|
||||
{
|
||||
if (select_it)
|
||||
{
|
||||
/* Switch back to WAIT_PID thread. */
|
||||
inferior_ptid = wait_ptid;
|
||||
|
||||
/* FIXME: This stuff came from switch_to_thread() in
|
||||
thread.c (which should probably be a public function). */
|
||||
flush_cached_frames ();
|
||||
registers_changed ();
|
||||
stop_pc = wait_pc;
|
||||
select_frame (get_current_frame (), 0);
|
||||
}
|
||||
/* We return 1 to indicate that there is a breakpoint here,
|
||||
so we need to step over it before continuing to avoid
|
||||
hitting it straight away. */
|
||||
if (breakpoint_here_p (wait_pc))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
init_frame_pc_noop (int fromleaf, struct frame_info *prev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
init_frame_pc_default (int fromleaf, struct frame_info *prev)
|
||||
{
|
||||
if (fromleaf)
|
||||
prev->pc = SAVED_PC_AFTER_CALL (prev->next);
|
||||
else if (prev->next != NULL)
|
||||
prev->pc = FRAME_SAVED_PC (prev->next);
|
||||
else
|
||||
prev->pc = read_pc ();
|
||||
}
|
||||
|
||||
void
|
||||
default_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
default_coff_make_msymbol_special (int val, struct minimal_symbol *msym)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
cannot_register_not (int regnum)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Legacy version of target_virtual_frame_pointer(). Assumes that
|
||||
there is an FP_REGNUM and that it is the same, cooked or raw. */
|
||||
|
||||
void
|
||||
legacy_virtual_frame_pointer (CORE_ADDR pc,
|
||||
int *frame_regnum,
|
||||
LONGEST *frame_offset)
|
||||
{
|
||||
gdb_assert (FP_REGNUM >= 0);
|
||||
*frame_regnum = FP_REGNUM;
|
||||
*frame_offset = 0;
|
||||
}
|
||||
|
||||
/* Assume the world is flat. Every register is large enough to fit a
|
||||
target integer. */
|
||||
|
||||
int
|
||||
generic_register_raw_size (int regnum)
|
||||
{
|
||||
gdb_assert (regnum >= 0 && regnum < NUM_REGS + NUM_PSEUDO_REGS);
|
||||
return TARGET_INT_BIT / HOST_CHAR_BIT;
|
||||
}
|
||||
|
||||
/* Assume the virtual size corresponds to the virtual type. */
|
||||
|
||||
int
|
||||
generic_register_virtual_size (int regnum)
|
||||
{
|
||||
return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum));
|
||||
}
|
||||
|
||||
|
||||
/* Functions to manipulate the endianness of the target. */
|
||||
|
||||
/* ``target_byte_order'' is only used when non- multi-arch.
|
||||
Multi-arch targets obtain the current byte order using the
|
||||
TARGET_BYTE_ORDER gdbarch method.
|
||||
|
||||
The choice of initial value is entirely arbitrary. During startup,
|
||||
the function initialize_current_architecture() updates this value
|
||||
based on default byte-order information extracted from BFD. */
|
||||
int target_byte_order = BFD_ENDIAN_BIG;
|
||||
int target_byte_order_auto = 1;
|
||||
|
||||
static const char endian_big[] = "big";
|
||||
static const char endian_little[] = "little";
|
||||
static const char endian_auto[] = "auto";
|
||||
static const char *endian_enum[] =
|
||||
{
|
||||
endian_big,
|
||||
endian_little,
|
||||
endian_auto,
|
||||
NULL,
|
||||
};
|
||||
static const char *set_endian_string;
|
||||
|
||||
/* Called by ``show endian''. */
|
||||
|
||||
static void
|
||||
show_endian (char *args, int from_tty)
|
||||
{
|
||||
if (TARGET_BYTE_ORDER_AUTO)
|
||||
printf_unfiltered ("The target endianness is set automatically (currently %s endian)\n",
|
||||
(TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little"));
|
||||
else
|
||||
printf_unfiltered ("The target is assumed to be %s endian\n",
|
||||
(TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little"));
|
||||
}
|
||||
|
||||
static void
|
||||
set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
if (set_endian_string == endian_auto)
|
||||
{
|
||||
target_byte_order_auto = 1;
|
||||
}
|
||||
else if (set_endian_string == endian_little)
|
||||
{
|
||||
target_byte_order_auto = 0;
|
||||
if (GDB_MULTI_ARCH)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
gdbarch_info_init (&info);
|
||||
info.byte_order = BFD_ENDIAN_LITTLE;
|
||||
if (! gdbarch_update_p (info))
|
||||
{
|
||||
printf_unfiltered ("Little endian target not supported by GDB\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target_byte_order = BFD_ENDIAN_LITTLE;
|
||||
}
|
||||
}
|
||||
else if (set_endian_string == endian_big)
|
||||
{
|
||||
target_byte_order_auto = 0;
|
||||
if (GDB_MULTI_ARCH)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
gdbarch_info_init (&info);
|
||||
info.byte_order = BFD_ENDIAN_BIG;
|
||||
if (! gdbarch_update_p (info))
|
||||
{
|
||||
printf_unfiltered ("Big endian target not supported by GDB\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target_byte_order = BFD_ENDIAN_BIG;
|
||||
}
|
||||
}
|
||||
else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"set_endian: bad value");
|
||||
show_endian (NULL, from_tty);
|
||||
}
|
||||
|
||||
/* Set the endianness from a BFD. */
|
||||
|
||||
static void
|
||||
set_endian_from_file (bfd *abfd)
|
||||
{
|
||||
int want;
|
||||
if (GDB_MULTI_ARCH)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"set_endian_from_file: not for multi-arch");
|
||||
if (bfd_big_endian (abfd))
|
||||
want = BFD_ENDIAN_BIG;
|
||||
else
|
||||
want = BFD_ENDIAN_LITTLE;
|
||||
if (TARGET_BYTE_ORDER_AUTO)
|
||||
target_byte_order = want;
|
||||
else if (TARGET_BYTE_ORDER != want)
|
||||
warning ("%s endian file does not match %s endian target.",
|
||||
want == BFD_ENDIAN_BIG ? "big" : "little",
|
||||
TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little");
|
||||
}
|
||||
|
||||
|
||||
/* Functions to manipulate the architecture of the target */
|
||||
|
||||
enum set_arch { set_arch_auto, set_arch_manual };
|
||||
|
||||
int target_architecture_auto = 1;
|
||||
|
||||
const char *set_architecture_string;
|
||||
|
||||
/* Old way of changing the current architecture. */
|
||||
|
||||
extern const struct bfd_arch_info bfd_default_arch_struct;
|
||||
const struct bfd_arch_info *target_architecture = &bfd_default_arch_struct;
|
||||
int (*target_architecture_hook) (const struct bfd_arch_info *ap);
|
||||
|
||||
static int
|
||||
arch_ok (const struct bfd_arch_info *arch)
|
||||
{
|
||||
if (GDB_MULTI_ARCH)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"arch_ok: not multi-arched");
|
||||
/* Should be performing the more basic check that the binary is
|
||||
compatible with GDB. */
|
||||
/* Check with the target that the architecture is valid. */
|
||||
return (target_architecture_hook == NULL
|
||||
|| target_architecture_hook (arch));
|
||||
}
|
||||
|
||||
static void
|
||||
set_arch (const struct bfd_arch_info *arch,
|
||||
enum set_arch type)
|
||||
{
|
||||
if (GDB_MULTI_ARCH)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"set_arch: not multi-arched");
|
||||
switch (type)
|
||||
{
|
||||
case set_arch_auto:
|
||||
if (!arch_ok (arch))
|
||||
warning ("Target may not support %s architecture",
|
||||
arch->printable_name);
|
||||
target_architecture = arch;
|
||||
break;
|
||||
case set_arch_manual:
|
||||
if (!arch_ok (arch))
|
||||
{
|
||||
printf_unfiltered ("Target does not support `%s' architecture.\n",
|
||||
arch->printable_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
target_architecture_auto = 0;
|
||||
target_architecture = arch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (gdbarch_debug)
|
||||
gdbarch_dump (current_gdbarch, gdb_stdlog);
|
||||
}
|
||||
|
||||
/* Set the architecture from arch/machine (deprecated) */
|
||||
|
||||
void
|
||||
set_architecture_from_arch_mach (enum bfd_architecture arch,
|
||||
unsigned long mach)
|
||||
{
|
||||
const struct bfd_arch_info *wanted = bfd_lookup_arch (arch, mach);
|
||||
if (GDB_MULTI_ARCH)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"set_architecture_from_arch_mach: not multi-arched");
|
||||
if (wanted != NULL)
|
||||
set_arch (wanted, set_arch_manual);
|
||||
else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"gdbarch: hardwired architecture/machine not recognized");
|
||||
}
|
||||
|
||||
/* Set the architecture from a BFD (deprecated) */
|
||||
|
||||
static void
|
||||
set_architecture_from_file (bfd *abfd)
|
||||
{
|
||||
const struct bfd_arch_info *wanted = bfd_get_arch_info (abfd);
|
||||
if (GDB_MULTI_ARCH)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"set_architecture_from_file: not multi-arched");
|
||||
if (target_architecture_auto)
|
||||
{
|
||||
set_arch (wanted, set_arch_auto);
|
||||
}
|
||||
else if (wanted != target_architecture)
|
||||
{
|
||||
warning ("%s architecture file may be incompatible with %s target.",
|
||||
wanted->printable_name,
|
||||
target_architecture->printable_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Called if the user enters ``show architecture'' without an
|
||||
argument. */
|
||||
|
||||
static void
|
||||
show_architecture (char *args, int from_tty)
|
||||
{
|
||||
const char *arch;
|
||||
arch = TARGET_ARCHITECTURE->printable_name;
|
||||
if (target_architecture_auto)
|
||||
printf_filtered ("The target architecture is set automatically (currently %s)\n", arch);
|
||||
else
|
||||
printf_filtered ("The target architecture is assumed to be %s\n", arch);
|
||||
}
|
||||
|
||||
|
||||
/* Called if the user enters ``set architecture'' with or without an
|
||||
argument. */
|
||||
|
||||
static void
|
||||
set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
if (strcmp (set_architecture_string, "auto") == 0)
|
||||
{
|
||||
target_architecture_auto = 1;
|
||||
}
|
||||
else if (GDB_MULTI_ARCH)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
gdbarch_info_init (&info);
|
||||
info.bfd_arch_info = bfd_scan_arch (set_architecture_string);
|
||||
if (info.bfd_arch_info == NULL)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"set_architecture: bfd_scan_arch failed");
|
||||
if (gdbarch_update_p (info))
|
||||
target_architecture_auto = 0;
|
||||
else
|
||||
printf_unfiltered ("Architecture `%s' not recognized.\n",
|
||||
set_architecture_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
const struct bfd_arch_info *arch
|
||||
= bfd_scan_arch (set_architecture_string);
|
||||
if (arch == NULL)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"set_architecture: bfd_scan_arch failed");
|
||||
set_arch (arch, set_arch_manual);
|
||||
}
|
||||
show_architecture (NULL, from_tty);
|
||||
}
|
||||
|
||||
/* Set the dynamic target-system-dependent parameters (architecture,
|
||||
byte-order) using information found in the BFD */
|
||||
|
||||
void
|
||||
set_gdbarch_from_file (bfd *abfd)
|
||||
{
|
||||
if (GDB_MULTI_ARCH)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
gdbarch_info_init (&info);
|
||||
info.abfd = abfd;
|
||||
if (! gdbarch_update_p (info))
|
||||
error ("Architecture of file not recognized.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
set_architecture_from_file (abfd);
|
||||
set_endian_from_file (abfd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the current architecture. Update the ``set
|
||||
architecture'' command so that it specifies a list of valid
|
||||
architectures. */
|
||||
|
||||
#ifdef DEFAULT_BFD_ARCH
|
||||
extern const bfd_arch_info_type DEFAULT_BFD_ARCH;
|
||||
static const bfd_arch_info_type *default_bfd_arch = &DEFAULT_BFD_ARCH;
|
||||
#else
|
||||
static const bfd_arch_info_type *default_bfd_arch;
|
||||
#endif
|
||||
|
||||
#ifdef DEFAULT_BFD_VEC
|
||||
extern const bfd_target DEFAULT_BFD_VEC;
|
||||
static const bfd_target *default_bfd_vec = &DEFAULT_BFD_VEC;
|
||||
#else
|
||||
static const bfd_target *default_bfd_vec;
|
||||
#endif
|
||||
|
||||
void
|
||||
initialize_current_architecture (void)
|
||||
{
|
||||
const char **arches = gdbarch_printable_names ();
|
||||
|
||||
/* determine a default architecture and byte order. */
|
||||
struct gdbarch_info info;
|
||||
gdbarch_info_init (&info);
|
||||
|
||||
/* Find a default architecture. */
|
||||
if (info.bfd_arch_info == NULL
|
||||
&& default_bfd_arch != NULL)
|
||||
info.bfd_arch_info = default_bfd_arch;
|
||||
if (info.bfd_arch_info == NULL)
|
||||
{
|
||||
/* Choose the architecture by taking the first one
|
||||
alphabetically. */
|
||||
const char *chosen = arches[0];
|
||||
const char **arch;
|
||||
for (arch = arches; *arch != NULL; arch++)
|
||||
{
|
||||
if (strcmp (*arch, chosen) < 0)
|
||||
chosen = *arch;
|
||||
}
|
||||
if (chosen == NULL)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"initialize_current_architecture: No arch");
|
||||
info.bfd_arch_info = bfd_scan_arch (chosen);
|
||||
if (info.bfd_arch_info == NULL)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"initialize_current_architecture: Arch not found");
|
||||
}
|
||||
|
||||
/* Take several guesses at a byte order. */
|
||||
if (info.byte_order == BFD_ENDIAN_UNKNOWN
|
||||
&& default_bfd_vec != NULL)
|
||||
{
|
||||
/* Extract BFD's default vector's byte order. */
|
||||
switch (default_bfd_vec->byteorder)
|
||||
{
|
||||
case BFD_ENDIAN_BIG:
|
||||
info.byte_order = BFD_ENDIAN_BIG;
|
||||
break;
|
||||
case BFD_ENDIAN_LITTLE:
|
||||
info.byte_order = BFD_ENDIAN_LITTLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (info.byte_order == BFD_ENDIAN_UNKNOWN)
|
||||
{
|
||||
/* look for ``*el-*'' in the target name. */
|
||||
const char *chp;
|
||||
chp = strchr (target_name, '-');
|
||||
if (chp != NULL
|
||||
&& chp - 2 >= target_name
|
||||
&& strncmp (chp - 2, "el", 2) == 0)
|
||||
info.byte_order = BFD_ENDIAN_LITTLE;
|
||||
}
|
||||
if (info.byte_order == BFD_ENDIAN_UNKNOWN)
|
||||
{
|
||||
/* Wire it to big-endian!!! */
|
||||
info.byte_order = BFD_ENDIAN_BIG;
|
||||
}
|
||||
|
||||
if (GDB_MULTI_ARCH)
|
||||
{
|
||||
if (! gdbarch_update_p (info))
|
||||
{
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"initialize_current_architecture: Selection of initial architecture failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the multi-arch logic comes up with a byte-order (from BFD)
|
||||
use it for the non-multi-arch case. */
|
||||
if (info.byte_order != BFD_ENDIAN_UNKNOWN)
|
||||
target_byte_order = info.byte_order;
|
||||
initialize_non_multiarch ();
|
||||
}
|
||||
|
||||
/* Create the ``set architecture'' command appending ``auto'' to the
|
||||
list of architectures. */
|
||||
{
|
||||
struct cmd_list_element *c;
|
||||
/* Append ``auto''. */
|
||||
int nr;
|
||||
for (nr = 0; arches[nr] != NULL; nr++);
|
||||
arches = xrealloc (arches, sizeof (char*) * (nr + 2));
|
||||
arches[nr + 0] = "auto";
|
||||
arches[nr + 1] = NULL;
|
||||
/* FIXME: add_set_enum_cmd() uses an array of ``char *'' instead
|
||||
of ``const char *''. We just happen to know that the casts are
|
||||
safe. */
|
||||
c = add_set_enum_cmd ("architecture", class_support,
|
||||
arches, &set_architecture_string,
|
||||
"Set architecture of target.",
|
||||
&setlist);
|
||||
set_cmd_sfunc (c, set_architecture);
|
||||
add_alias_cmd ("processor", "architecture", class_support, 1, &setlist);
|
||||
/* Don't use set_from_show - need to print both auto/manual and
|
||||
current setting. */
|
||||
add_cmd ("architecture", class_support, show_architecture,
|
||||
"Show the current target architecture", &showlist);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialize a gdbarch info to values that will be automatically
|
||||
overridden. Note: Originally, this ``struct info'' was initialized
|
||||
using memset(0). Unfortunatly, that ran into problems, namely
|
||||
BFD_ENDIAN_BIG is zero. An explicit initialization function that
|
||||
can explicitly set each field to a well defined value is used. */
|
||||
|
||||
void
|
||||
gdbarch_info_init (struct gdbarch_info *info)
|
||||
{
|
||||
memset (info, 0, sizeof (struct gdbarch_info));
|
||||
info->byte_order = BFD_ENDIAN_UNKNOWN;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
extern initialize_file_ftype _initialize_gdbarch_utils;
|
||||
|
||||
void
|
||||
_initialize_gdbarch_utils (void)
|
||||
{
|
||||
struct cmd_list_element *c;
|
||||
c = add_set_enum_cmd ("endian", class_support,
|
||||
endian_enum, &set_endian_string,
|
||||
"Set endianness of target.",
|
||||
&setlist);
|
||||
set_cmd_sfunc (c, set_endian);
|
||||
/* Don't use set_from_show - need to print both auto/manual and
|
||||
current setting. */
|
||||
add_cmd ("endian", class_support, show_endian,
|
||||
"Show the current byte-order", &showlist);
|
||||
}
|
||||
163
gdb/arch-utils.h
163
gdb/arch-utils.h
@@ -1,163 +0,0 @@
|
||||
/* Dynamic architecture support for GDB, the GNU debugger.
|
||||
Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef GDBARCH_UTILS_H
|
||||
#define GDBARCH_UTILS_H
|
||||
|
||||
/* gdbarch trace variable */
|
||||
extern int gdbarch_debug;
|
||||
|
||||
/* Fallback for register convertible. */
|
||||
extern gdbarch_register_convertible_ftype generic_register_convertible_not;
|
||||
|
||||
extern CORE_ADDR generic_cannot_extract_struct_value_address (char *dummy);
|
||||
|
||||
/* Helper function for targets that don't know how my arguments are
|
||||
being passed */
|
||||
extern gdbarch_frame_num_args_ftype frame_num_args_unknown;
|
||||
|
||||
/* Implementation of breakpoint from PC using any of the deprecated
|
||||
macros BREAKPOINT, LITTLE_BREAKPOINT, BIG_BREAPOINT. For legacy
|
||||
targets that don't yet implement their own breakpoint_from_pc(). */
|
||||
extern gdbarch_breakpoint_from_pc_ftype legacy_breakpoint_from_pc;
|
||||
|
||||
/* Frameless functions not identifable. */
|
||||
extern gdbarch_frameless_function_invocation_ftype generic_frameless_function_invocation_not;
|
||||
|
||||
/* Only structures, unions, and arrays are returned using the struct
|
||||
convention. Note that arrays are never passed by value in the C
|
||||
language family, so that case is irrelevant for C. */
|
||||
extern gdbarch_return_value_on_stack_ftype generic_return_value_on_stack_not;
|
||||
|
||||
/* Map onto old REGISTER_NAMES. */
|
||||
extern char *legacy_register_name (int i);
|
||||
|
||||
/* Accessor for old global function pointer for disassembly. */
|
||||
extern int legacy_print_insn (bfd_vma vma, disassemble_info *info);
|
||||
|
||||
/* Backward compatible call_dummy_words. */
|
||||
extern LONGEST legacy_call_dummy_words[];
|
||||
extern int legacy_sizeof_call_dummy_words;
|
||||
|
||||
/* Typical remote_translate_xfer_address */
|
||||
extern gdbarch_remote_translate_xfer_address_ftype generic_remote_translate_xfer_address;
|
||||
|
||||
/* Generic implementation of prologue_frameless_p. Just calls
|
||||
SKIP_PROLOG and checks the return value to see if it actually
|
||||
changed. */
|
||||
extern gdbarch_prologue_frameless_p_ftype generic_prologue_frameless_p;
|
||||
|
||||
/* The only possible cases for inner_than. */
|
||||
extern int core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs);
|
||||
extern int core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs);
|
||||
|
||||
/* Floating point values. */
|
||||
extern const struct floatformat *default_float_format (struct gdbarch *gdbarch);
|
||||
extern const struct floatformat *default_double_format (struct gdbarch *gdbarch);
|
||||
|
||||
/* Helper function for targets that don't know how my arguments are
|
||||
being passed */
|
||||
extern int frame_num_args_unknown (struct frame_info *fi);
|
||||
|
||||
|
||||
/* The following DEPRECATED interfaces are for pre- multi-arch legacy
|
||||
targets. */
|
||||
|
||||
/* DEPRECATED pre- multi-arch interface. Explicitly set the dynamic
|
||||
target-system-dependent parameters based on bfd_architecture and
|
||||
machine. This function is deprecated, use
|
||||
set_gdbarch_from_arch_machine(). */
|
||||
|
||||
extern void set_architecture_from_arch_mach (enum bfd_architecture, unsigned long);
|
||||
|
||||
/* DEPRECATED pre- multi-arch interface. Notify the target dependent
|
||||
backend of a change to the selected architecture. A zero return
|
||||
status indicates that the target did not like the change. */
|
||||
|
||||
extern int (*target_architecture_hook) (const struct bfd_arch_info *);
|
||||
|
||||
|
||||
/* Default raw->sim register re-numbering - does nothing. */
|
||||
|
||||
extern int default_register_sim_regno (int reg_nr);
|
||||
|
||||
/* Identity function on a CORE_ADDR. Just returns its parameter. */
|
||||
|
||||
extern CORE_ADDR core_addr_identity (CORE_ADDR addr);
|
||||
|
||||
/* No-op conversion of reg to regnum. */
|
||||
|
||||
extern int no_op_reg_to_regnum (int reg);
|
||||
|
||||
/* Default frame_args_address and frame_locals_address. */
|
||||
|
||||
extern CORE_ADDR default_frame_address (struct frame_info *);
|
||||
|
||||
/* Default prepare_to_procced. */
|
||||
|
||||
extern int default_prepare_to_proceed (int select_it);
|
||||
|
||||
extern int generic_prepare_to_proceed (int select_it);
|
||||
|
||||
/* Versions of init_frame_pc(). Do nothing; do the default. */
|
||||
|
||||
void init_frame_pc_noop (int fromleaf, struct frame_info *prev);
|
||||
|
||||
void init_frame_pc_default (int fromleaf, struct frame_info *prev);
|
||||
|
||||
/* Do nothing version of elf_make_msymbol_special. */
|
||||
|
||||
void default_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym);
|
||||
|
||||
/* Do nothing version of coff_make_msymbol_special. */
|
||||
|
||||
void default_coff_make_msymbol_special (int val, struct minimal_symbol *msym);
|
||||
|
||||
/* Version of cannot_fetch_register() / cannot_store_register() that
|
||||
always fails. */
|
||||
|
||||
int cannot_register_not (int regnum);
|
||||
|
||||
/* Legacy version of target_virtual_frame_pointer(). Assumes that
|
||||
there is an FP_REGNUM and that it is the same, cooked or raw. */
|
||||
|
||||
extern gdbarch_virtual_frame_pointer_ftype legacy_virtual_frame_pointer;
|
||||
|
||||
extern CORE_ADDR generic_skip_trampoline_code (CORE_ADDR pc);
|
||||
|
||||
extern int generic_in_solib_call_trampoline (CORE_ADDR pc, char *name);
|
||||
|
||||
extern int generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc);
|
||||
|
||||
extern void default_print_float_info (void);
|
||||
|
||||
/* Assume all registers are the same size and a size identical to that
|
||||
of the integer type. */
|
||||
extern int generic_register_raw_size (int regnum);
|
||||
|
||||
/* Assume the virtual size of registers corresponds to the virtual type. */
|
||||
|
||||
extern int generic_register_virtual_size (int regnum);
|
||||
|
||||
/* Initialize a ``struct info''. Can't use memset(0) since some
|
||||
default values are not zero. */
|
||||
extern void gdbarch_info_init (struct gdbarch_info *info);
|
||||
|
||||
#endif
|
||||
@@ -1,694 +0,0 @@
|
||||
/* GNU/Linux on ARM native support.
|
||||
Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
#include "gdbcore.h"
|
||||
#include "gdb_string.h"
|
||||
#include "regcache.h"
|
||||
|
||||
#include <sys/user.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/procfs.h>
|
||||
|
||||
/* Prototypes for supply_gregset etc. */
|
||||
#include "gregset.h"
|
||||
|
||||
extern int arm_apcs_32;
|
||||
|
||||
#define typeNone 0x00
|
||||
#define typeSingle 0x01
|
||||
#define typeDouble 0x02
|
||||
#define typeExtended 0x03
|
||||
#define FPWORDS 28
|
||||
#define CPSR_REGNUM 16
|
||||
|
||||
typedef union tagFPREG
|
||||
{
|
||||
unsigned int fSingle;
|
||||
unsigned int fDouble[2];
|
||||
unsigned int fExtended[3];
|
||||
}
|
||||
FPREG;
|
||||
|
||||
typedef struct tagFPA11
|
||||
{
|
||||
FPREG fpreg[8]; /* 8 floating point registers */
|
||||
unsigned int fpsr; /* floating point status register */
|
||||
unsigned int fpcr; /* floating point control register */
|
||||
unsigned char fType[8]; /* type of floating point value held in
|
||||
floating point registers. */
|
||||
int initflag; /* NWFPE initialization flag. */
|
||||
}
|
||||
FPA11;
|
||||
|
||||
/* The following variables are used to determine the version of the
|
||||
underlying Linux operating system. Examples:
|
||||
|
||||
Linux 2.0.35 Linux 2.2.12
|
||||
os_version = 0x00020023 os_version = 0x0002020c
|
||||
os_major = 2 os_major = 2
|
||||
os_minor = 0 os_minor = 2
|
||||
os_release = 35 os_release = 12
|
||||
|
||||
Note: os_version = (os_major << 16) | (os_minor << 8) | os_release
|
||||
|
||||
These are initialized using get_linux_version() from
|
||||
_initialize_arm_linux_nat(). */
|
||||
|
||||
static unsigned int os_version, os_major, os_minor, os_release;
|
||||
|
||||
/* On Linux, threads are implemented as pseudo-processes, in which
|
||||
case we may be tracing more than one process at a time. In that
|
||||
case, inferior_ptid will contain the main process ID and the
|
||||
individual thread (process) ID. get_thread_id () is used to
|
||||
get the thread id if it's available, and the process id otherwise. */
|
||||
|
||||
int
|
||||
get_thread_id (ptid_t ptid)
|
||||
{
|
||||
int tid = TIDGET (ptid);
|
||||
if (0 == tid)
|
||||
tid = PIDGET (ptid);
|
||||
return tid;
|
||||
}
|
||||
#define GET_THREAD_ID(PTID) get_thread_id ((PTID));
|
||||
|
||||
static void
|
||||
fetch_nwfpe_single (unsigned int fn, FPA11 * fpa11)
|
||||
{
|
||||
unsigned int mem[3];
|
||||
|
||||
mem[0] = fpa11->fpreg[fn].fSingle;
|
||||
mem[1] = 0;
|
||||
mem[2] = 0;
|
||||
supply_register (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_nwfpe_double (unsigned int fn, FPA11 * fpa11)
|
||||
{
|
||||
unsigned int mem[3];
|
||||
|
||||
mem[0] = fpa11->fpreg[fn].fDouble[1];
|
||||
mem[1] = fpa11->fpreg[fn].fDouble[0];
|
||||
mem[2] = 0;
|
||||
supply_register (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_nwfpe_none (unsigned int fn)
|
||||
{
|
||||
unsigned int mem[3] =
|
||||
{0, 0, 0};
|
||||
|
||||
supply_register (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
|
||||
{
|
||||
unsigned int mem[3];
|
||||
|
||||
mem[0] = fpa11->fpreg[fn].fExtended[0]; /* sign & exponent */
|
||||
mem[1] = fpa11->fpreg[fn].fExtended[2]; /* ls bits */
|
||||
mem[2] = fpa11->fpreg[fn].fExtended[1]; /* ms bits */
|
||||
supply_register (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_nwfpe_register (int regno, FPA11 * fpa11)
|
||||
{
|
||||
int fn = regno - F0_REGNUM;
|
||||
|
||||
switch (fpa11->fType[fn])
|
||||
{
|
||||
case typeSingle:
|
||||
fetch_nwfpe_single (fn, fpa11);
|
||||
break;
|
||||
|
||||
case typeDouble:
|
||||
fetch_nwfpe_double (fn, fpa11);
|
||||
break;
|
||||
|
||||
case typeExtended:
|
||||
fetch_nwfpe_extended (fn, fpa11);
|
||||
break;
|
||||
|
||||
default:
|
||||
fetch_nwfpe_none (fn);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
store_nwfpe_single (unsigned int fn, FPA11 * fpa11)
|
||||
{
|
||||
unsigned int mem[3];
|
||||
|
||||
read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
fpa11->fpreg[fn].fSingle = mem[0];
|
||||
fpa11->fType[fn] = typeSingle;
|
||||
}
|
||||
|
||||
static void
|
||||
store_nwfpe_double (unsigned int fn, FPA11 * fpa11)
|
||||
{
|
||||
unsigned int mem[3];
|
||||
|
||||
read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
fpa11->fpreg[fn].fDouble[1] = mem[0];
|
||||
fpa11->fpreg[fn].fDouble[0] = mem[1];
|
||||
fpa11->fType[fn] = typeDouble;
|
||||
}
|
||||
|
||||
void
|
||||
store_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
|
||||
{
|
||||
unsigned int mem[3];
|
||||
|
||||
read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
fpa11->fpreg[fn].fExtended[0] = mem[0]; /* sign & exponent */
|
||||
fpa11->fpreg[fn].fExtended[2] = mem[1]; /* ls bits */
|
||||
fpa11->fpreg[fn].fExtended[1] = mem[2]; /* ms bits */
|
||||
fpa11->fType[fn] = typeDouble;
|
||||
}
|
||||
|
||||
void
|
||||
store_nwfpe_register (int regno, FPA11 * fpa11)
|
||||
{
|
||||
if (register_cached (regno))
|
||||
{
|
||||
unsigned int fn = regno - F0_REGNUM;
|
||||
switch (fpa11->fType[fn])
|
||||
{
|
||||
case typeSingle:
|
||||
store_nwfpe_single (fn, fpa11);
|
||||
break;
|
||||
|
||||
case typeDouble:
|
||||
store_nwfpe_double (fn, fpa11);
|
||||
break;
|
||||
|
||||
case typeExtended:
|
||||
store_nwfpe_extended (fn, fpa11);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get the value of a particular register from the floating point
|
||||
state of the process and store it into regcache. */
|
||||
|
||||
static void
|
||||
fetch_fpregister (int regno)
|
||||
{
|
||||
int ret, tid;
|
||||
FPA11 fp;
|
||||
|
||||
/* Get the thread id for the ptrace call. */
|
||||
tid = GET_THREAD_ID (inferior_ptid);
|
||||
|
||||
/* Read the floating point state. */
|
||||
ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to fetch floating point register.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fetch fpsr. */
|
||||
if (FPS_REGNUM == regno)
|
||||
supply_register (FPS_REGNUM, (char *) &fp.fpsr);
|
||||
|
||||
/* Fetch the floating point register. */
|
||||
if (regno >= F0_REGNUM && regno <= F7_REGNUM)
|
||||
{
|
||||
int fn = regno - F0_REGNUM;
|
||||
|
||||
switch (fp.fType[fn])
|
||||
{
|
||||
case typeSingle:
|
||||
fetch_nwfpe_single (fn, &fp);
|
||||
break;
|
||||
|
||||
case typeDouble:
|
||||
fetch_nwfpe_double (fn, &fp);
|
||||
break;
|
||||
|
||||
case typeExtended:
|
||||
fetch_nwfpe_extended (fn, &fp);
|
||||
break;
|
||||
|
||||
default:
|
||||
fetch_nwfpe_none (fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the whole floating point state of the process and store it
|
||||
into regcache. */
|
||||
|
||||
static void
|
||||
fetch_fpregs (void)
|
||||
{
|
||||
int ret, regno, tid;
|
||||
FPA11 fp;
|
||||
|
||||
/* Get the thread id for the ptrace call. */
|
||||
tid = GET_THREAD_ID (inferior_ptid);
|
||||
|
||||
/* Read the floating point state. */
|
||||
ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to fetch the floating point registers.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fetch fpsr. */
|
||||
supply_register (FPS_REGNUM, (char *) &fp.fpsr);
|
||||
|
||||
/* Fetch the floating point registers. */
|
||||
for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
|
||||
{
|
||||
int fn = regno - F0_REGNUM;
|
||||
|
||||
switch (fp.fType[fn])
|
||||
{
|
||||
case typeSingle:
|
||||
fetch_nwfpe_single (fn, &fp);
|
||||
break;
|
||||
|
||||
case typeDouble:
|
||||
fetch_nwfpe_double (fn, &fp);
|
||||
break;
|
||||
|
||||
case typeExtended:
|
||||
fetch_nwfpe_extended (fn, &fp);
|
||||
break;
|
||||
|
||||
default:
|
||||
fetch_nwfpe_none (fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Save a particular register into the floating point state of the
|
||||
process using the contents from regcache. */
|
||||
|
||||
static void
|
||||
store_fpregister (int regno)
|
||||
{
|
||||
int ret, tid;
|
||||
FPA11 fp;
|
||||
|
||||
/* Get the thread id for the ptrace call. */
|
||||
tid = GET_THREAD_ID (inferior_ptid);
|
||||
|
||||
/* Read the floating point state. */
|
||||
ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to fetch the floating point registers.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store fpsr. */
|
||||
if (FPS_REGNUM == regno && register_cached (FPS_REGNUM))
|
||||
read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
|
||||
|
||||
/* Store the floating point register. */
|
||||
if (regno >= F0_REGNUM && regno <= F7_REGNUM)
|
||||
{
|
||||
store_nwfpe_register (regno, &fp);
|
||||
}
|
||||
|
||||
ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to store floating point register.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the whole floating point state of the process using
|
||||
the contents from regcache. */
|
||||
|
||||
static void
|
||||
store_fpregs (void)
|
||||
{
|
||||
int ret, regno, tid;
|
||||
FPA11 fp;
|
||||
|
||||
/* Get the thread id for the ptrace call. */
|
||||
tid = GET_THREAD_ID (inferior_ptid);
|
||||
|
||||
/* Read the floating point state. */
|
||||
ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to fetch the floating point registers.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store fpsr. */
|
||||
if (register_cached (FPS_REGNUM))
|
||||
read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
|
||||
|
||||
/* Store the floating point registers. */
|
||||
for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
|
||||
{
|
||||
fetch_nwfpe_register (regno, &fp);
|
||||
}
|
||||
|
||||
ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to store floating point registers.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch a general register of the process and store into
|
||||
regcache. */
|
||||
|
||||
static void
|
||||
fetch_register (int regno)
|
||||
{
|
||||
int ret, tid;
|
||||
elf_gregset_t regs;
|
||||
|
||||
/* Get the thread id for the ptrace call. */
|
||||
tid = GET_THREAD_ID (inferior_ptid);
|
||||
|
||||
ret = ptrace (PTRACE_GETREGS, tid, 0, ®s);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to fetch general register.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (regno >= A1_REGNUM && regno < PC_REGNUM)
|
||||
supply_register (regno, (char *) ®s[regno]);
|
||||
|
||||
if (PS_REGNUM == regno)
|
||||
{
|
||||
if (arm_apcs_32)
|
||||
supply_register (PS_REGNUM, (char *) ®s[CPSR_REGNUM]);
|
||||
else
|
||||
supply_register (PS_REGNUM, (char *) ®s[PC_REGNUM]);
|
||||
}
|
||||
|
||||
if (PC_REGNUM == regno)
|
||||
{
|
||||
regs[PC_REGNUM] = ADDR_BITS_REMOVE (regs[PC_REGNUM]);
|
||||
supply_register (PC_REGNUM, (char *) ®s[PC_REGNUM]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch all general registers of the process and store into
|
||||
regcache. */
|
||||
|
||||
static void
|
||||
fetch_regs (void)
|
||||
{
|
||||
int ret, regno, tid;
|
||||
elf_gregset_t regs;
|
||||
|
||||
/* Get the thread id for the ptrace call. */
|
||||
tid = GET_THREAD_ID (inferior_ptid);
|
||||
|
||||
ret = ptrace (PTRACE_GETREGS, tid, 0, ®s);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to fetch general registers.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
|
||||
supply_register (regno, (char *) ®s[regno]);
|
||||
|
||||
if (arm_apcs_32)
|
||||
supply_register (PS_REGNUM, (char *) ®s[CPSR_REGNUM]);
|
||||
else
|
||||
supply_register (PS_REGNUM, (char *) ®s[PC_REGNUM]);
|
||||
|
||||
regs[PC_REGNUM] = ADDR_BITS_REMOVE (regs[PC_REGNUM]);
|
||||
supply_register (PC_REGNUM, (char *) ®s[PC_REGNUM]);
|
||||
}
|
||||
|
||||
/* Store all general registers of the process from the values in
|
||||
regcache. */
|
||||
|
||||
static void
|
||||
store_register (int regno)
|
||||
{
|
||||
int ret, tid;
|
||||
elf_gregset_t regs;
|
||||
|
||||
if (!register_cached (regno))
|
||||
return;
|
||||
|
||||
/* Get the thread id for the ptrace call. */
|
||||
tid = GET_THREAD_ID (inferior_ptid);
|
||||
|
||||
/* Get the general registers from the process. */
|
||||
ret = ptrace (PTRACE_GETREGS, tid, 0, ®s);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to fetch general registers.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (regno >= A1_REGNUM && regno <= PC_REGNUM)
|
||||
read_register_gen (regno, (char *) ®s[regno]);
|
||||
|
||||
ret = ptrace (PTRACE_SETREGS, tid, 0, ®s);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to store general register.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
store_regs (void)
|
||||
{
|
||||
int ret, regno, tid;
|
||||
elf_gregset_t regs;
|
||||
|
||||
/* Get the thread id for the ptrace call. */
|
||||
tid = GET_THREAD_ID (inferior_ptid);
|
||||
|
||||
/* Fetch the general registers. */
|
||||
ret = ptrace (PTRACE_GETREGS, tid, 0, ®s);
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to fetch general registers.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (regno = A1_REGNUM; regno <= PC_REGNUM; regno++)
|
||||
{
|
||||
if (register_cached (regno))
|
||||
read_register_gen (regno, (char *) ®s[regno]);
|
||||
}
|
||||
|
||||
ret = ptrace (PTRACE_SETREGS, tid, 0, ®s);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
warning ("Unable to store general registers.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch registers from the child process. Fetch all registers if
|
||||
regno == -1, otherwise fetch all general registers or all floating
|
||||
point registers depending upon the value of regno. */
|
||||
|
||||
void
|
||||
fetch_inferior_registers (int regno)
|
||||
{
|
||||
if (-1 == regno)
|
||||
{
|
||||
fetch_regs ();
|
||||
fetch_fpregs ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (regno < F0_REGNUM || regno > FPS_REGNUM)
|
||||
fetch_register (regno);
|
||||
|
||||
if (regno >= F0_REGNUM && regno <= FPS_REGNUM)
|
||||
fetch_fpregister (regno);
|
||||
}
|
||||
}
|
||||
|
||||
/* Store registers back into the inferior. Store all registers if
|
||||
regno == -1, otherwise store all general registers or all floating
|
||||
point registers depending upon the value of regno. */
|
||||
|
||||
void
|
||||
store_inferior_registers (int regno)
|
||||
{
|
||||
if (-1 == regno)
|
||||
{
|
||||
store_regs ();
|
||||
store_fpregs ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((regno < F0_REGNUM) || (regno > FPS_REGNUM))
|
||||
store_register (regno);
|
||||
|
||||
if ((regno >= F0_REGNUM) && (regno <= FPS_REGNUM))
|
||||
store_fpregister (regno);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill register regno (if it is a general-purpose register) in
|
||||
*gregsetp with the appropriate value from GDB's register array.
|
||||
If regno is -1, do this for all registers. */
|
||||
|
||||
void
|
||||
fill_gregset (gdb_gregset_t *gregsetp, int regno)
|
||||
{
|
||||
if (-1 == regno)
|
||||
{
|
||||
int regnum;
|
||||
for (regnum = A1_REGNUM; regnum <= PC_REGNUM; regnum++)
|
||||
read_register_gen (regnum, (char *) &(*gregsetp)[regnum]);
|
||||
}
|
||||
else if (regno >= A1_REGNUM && regno <= PC_REGNUM)
|
||||
read_register_gen (regno, (char *) &(*gregsetp)[regno]);
|
||||
|
||||
if (PS_REGNUM == regno || -1 == regno)
|
||||
{
|
||||
if (arm_apcs_32)
|
||||
read_register_gen (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]);
|
||||
else
|
||||
read_register_gen (PC_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill GDB's register array with the general-purpose register values
|
||||
in *gregsetp. */
|
||||
|
||||
void
|
||||
supply_gregset (gdb_gregset_t *gregsetp)
|
||||
{
|
||||
int regno, reg_pc;
|
||||
|
||||
for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
|
||||
supply_register (regno, (char *) &(*gregsetp)[regno]);
|
||||
|
||||
if (arm_apcs_32)
|
||||
supply_register (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]);
|
||||
else
|
||||
supply_register (PS_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]);
|
||||
|
||||
reg_pc = ADDR_BITS_REMOVE ((CORE_ADDR)(*gregsetp)[PC_REGNUM]);
|
||||
supply_register (PC_REGNUM, (char *) ®_pc);
|
||||
}
|
||||
|
||||
/* Fill register regno (if it is a floating-point register) in
|
||||
*fpregsetp with the appropriate value from GDB's register array.
|
||||
If regno is -1, do this for all registers. */
|
||||
|
||||
void
|
||||
fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
|
||||
{
|
||||
FPA11 *fp = (FPA11 *) fpregsetp;
|
||||
|
||||
if (-1 == regno)
|
||||
{
|
||||
int regnum;
|
||||
for (regnum = F0_REGNUM; regnum <= F7_REGNUM; regnum++)
|
||||
store_nwfpe_register (regnum, fp);
|
||||
}
|
||||
else if (regno >= F0_REGNUM && regno <= F7_REGNUM)
|
||||
{
|
||||
store_nwfpe_register (regno, fp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store fpsr. */
|
||||
if (FPS_REGNUM == regno || -1 == regno)
|
||||
read_register_gen (FPS_REGNUM, (char *) &fp->fpsr);
|
||||
}
|
||||
|
||||
/* Fill GDB's register array with the floating-point register values
|
||||
in *fpregsetp. */
|
||||
|
||||
void
|
||||
supply_fpregset (gdb_fpregset_t *fpregsetp)
|
||||
{
|
||||
int regno;
|
||||
FPA11 *fp = (FPA11 *) fpregsetp;
|
||||
|
||||
/* Fetch fpsr. */
|
||||
supply_register (FPS_REGNUM, (char *) &fp->fpsr);
|
||||
|
||||
/* Fetch the floating point registers. */
|
||||
for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
|
||||
{
|
||||
fetch_nwfpe_register (regno, fp);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
arm_linux_kernel_u_size (void)
|
||||
{
|
||||
return (sizeof (struct user));
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_linux_version (unsigned int *vmajor,
|
||||
unsigned int *vminor,
|
||||
unsigned int *vrelease)
|
||||
{
|
||||
struct utsname info;
|
||||
char *pmajor, *pminor, *prelease, *tail;
|
||||
|
||||
if (-1 == uname (&info))
|
||||
{
|
||||
warning ("Unable to determine Linux version.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pmajor = strtok (info.release, ".");
|
||||
pminor = strtok (NULL, ".");
|
||||
prelease = strtok (NULL, ".");
|
||||
|
||||
*vmajor = (unsigned int) strtoul (pmajor, &tail, 0);
|
||||
*vminor = (unsigned int) strtoul (pminor, &tail, 0);
|
||||
*vrelease = (unsigned int) strtoul (prelease, &tail, 0);
|
||||
|
||||
return ((*vmajor << 16) | (*vminor << 8) | *vrelease);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_arm_linux_nat (void)
|
||||
{
|
||||
os_version = get_linux_version (&os_major, &os_minor, &os_release);
|
||||
}
|
||||
@@ -1,533 +0,0 @@
|
||||
/* GNU/Linux on ARM target support.
|
||||
Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "target.h"
|
||||
#include "value.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "floatformat.h"
|
||||
#include "gdbcore.h"
|
||||
#include "frame.h"
|
||||
#include "regcache.h"
|
||||
#include "doublest.h"
|
||||
|
||||
/* For arm_linux_skip_solib_resolver. */
|
||||
#include "symtab.h"
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
|
||||
/* CALL_DUMMY_WORDS:
|
||||
This sequence of words is the instructions
|
||||
|
||||
mov lr, pc
|
||||
mov pc, r4
|
||||
swi bkpt_swi
|
||||
|
||||
Note this is 12 bytes. */
|
||||
|
||||
LONGEST arm_linux_call_dummy_words[] =
|
||||
{
|
||||
0xe1a0e00f, 0xe1a0f004, 0xef9f001
|
||||
};
|
||||
|
||||
#ifdef GET_LONGJMP_TARGET
|
||||
|
||||
/* Figure out where the longjmp will land. We expect that we have
|
||||
just entered longjmp and haven't yet altered r0, r1, so the
|
||||
arguments are still in the registers. (A1_REGNUM) points at the
|
||||
jmp_buf structure from which we extract the pc (JB_PC) that we will
|
||||
land at. The pc is copied into ADDR. This routine returns true on
|
||||
success. */
|
||||
|
||||
#define LONGJMP_TARGET_SIZE sizeof(int)
|
||||
#define JB_ELEMENT_SIZE sizeof(int)
|
||||
#define JB_SL 18
|
||||
#define JB_FP 19
|
||||
#define JB_SP 20
|
||||
#define JB_PC 21
|
||||
|
||||
int
|
||||
arm_get_longjmp_target (CORE_ADDR * pc)
|
||||
{
|
||||
CORE_ADDR jb_addr;
|
||||
char buf[LONGJMP_TARGET_SIZE];
|
||||
|
||||
jb_addr = read_register (A1_REGNUM);
|
||||
|
||||
if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
|
||||
LONGJMP_TARGET_SIZE))
|
||||
return 0;
|
||||
|
||||
*pc = extract_address (buf, LONGJMP_TARGET_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* GET_LONGJMP_TARGET */
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state
|
||||
a function return value of type TYPE, and copy that, in virtual format,
|
||||
into VALBUF. */
|
||||
|
||||
void
|
||||
arm_linux_extract_return_value (struct type *type,
|
||||
char regbuf[REGISTER_BYTES],
|
||||
char *valbuf)
|
||||
{
|
||||
/* ScottB: This needs to be looked at to handle the different
|
||||
floating point emulators on ARM Linux. Right now the code
|
||||
assumes that fetch inferior registers does the right thing for
|
||||
GDB. I suspect this won't handle NWFPE registers correctly, nor
|
||||
will the default ARM version (arm_extract_return_value()). */
|
||||
|
||||
int regnum = (TYPE_CODE_FLT == TYPE_CODE (type)) ? F0_REGNUM : A1_REGNUM;
|
||||
memcpy (valbuf, ®buf[REGISTER_BYTE (regnum)], TYPE_LENGTH (type));
|
||||
}
|
||||
|
||||
/* Note: ScottB
|
||||
|
||||
This function does not support passing parameters using the FPA
|
||||
variant of the APCS. It passes any floating point arguments in the
|
||||
general registers and/or on the stack.
|
||||
|
||||
FIXME: This and arm_push_arguments should be merged. However this
|
||||
function breaks on a little endian host, big endian target
|
||||
using the COFF file format. ELF is ok.
|
||||
|
||||
ScottB. */
|
||||
|
||||
/* Addresses for calling Thumb functions have the bit 0 set.
|
||||
Here are some macros to test, set, or clear bit 0 of addresses. */
|
||||
#define IS_THUMB_ADDR(addr) ((addr) & 1)
|
||||
#define MAKE_THUMB_ADDR(addr) ((addr) | 1)
|
||||
#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
|
||||
|
||||
CORE_ADDR
|
||||
arm_linux_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
||||
int struct_return, CORE_ADDR struct_addr)
|
||||
{
|
||||
char *fp;
|
||||
int argnum, argreg, nstack_size;
|
||||
|
||||
/* Walk through the list of args and determine how large a temporary
|
||||
stack is required. Need to take care here as structs may be
|
||||
passed on the stack, and we have to to push them. */
|
||||
nstack_size = -4 * REGISTER_SIZE; /* Some arguments go into A1-A4. */
|
||||
|
||||
if (struct_return) /* The struct address goes in A1. */
|
||||
nstack_size += REGISTER_SIZE;
|
||||
|
||||
/* Walk through the arguments and add their size to nstack_size. */
|
||||
for (argnum = 0; argnum < nargs; argnum++)
|
||||
{
|
||||
int len;
|
||||
struct type *arg_type;
|
||||
|
||||
arg_type = check_typedef (VALUE_TYPE (args[argnum]));
|
||||
len = TYPE_LENGTH (arg_type);
|
||||
|
||||
/* ANSI C code passes float arguments as integers, K&R code
|
||||
passes float arguments as doubles. Correct for this here. */
|
||||
if (TYPE_CODE_FLT == TYPE_CODE (arg_type) && REGISTER_SIZE == len)
|
||||
nstack_size += FP_REGISTER_VIRTUAL_SIZE;
|
||||
else
|
||||
nstack_size += len;
|
||||
}
|
||||
|
||||
/* Allocate room on the stack, and initialize our stack frame
|
||||
pointer. */
|
||||
fp = NULL;
|
||||
if (nstack_size > 0)
|
||||
{
|
||||
sp -= nstack_size;
|
||||
fp = (char *) sp;
|
||||
}
|
||||
|
||||
/* Initialize the integer argument register pointer. */
|
||||
argreg = A1_REGNUM;
|
||||
|
||||
/* The struct_return pointer occupies the first parameter passing
|
||||
register. */
|
||||
if (struct_return)
|
||||
write_register (argreg++, struct_addr);
|
||||
|
||||
/* Process arguments from left to right. Store as many as allowed
|
||||
in the parameter passing registers (A1-A4), and save the rest on
|
||||
the temporary stack. */
|
||||
for (argnum = 0; argnum < nargs; argnum++)
|
||||
{
|
||||
int len;
|
||||
char *val;
|
||||
CORE_ADDR regval;
|
||||
enum type_code typecode;
|
||||
struct type *arg_type, *target_type;
|
||||
|
||||
arg_type = check_typedef (VALUE_TYPE (args[argnum]));
|
||||
target_type = TYPE_TARGET_TYPE (arg_type);
|
||||
len = TYPE_LENGTH (arg_type);
|
||||
typecode = TYPE_CODE (arg_type);
|
||||
val = (char *) VALUE_CONTENTS (args[argnum]);
|
||||
|
||||
/* ANSI C code passes float arguments as integers, K&R code
|
||||
passes float arguments as doubles. The .stabs record for
|
||||
for ANSI prototype floating point arguments records the
|
||||
type as FP_INTEGER, while a K&R style (no prototype)
|
||||
.stabs records the type as FP_FLOAT. In this latter case
|
||||
the compiler converts the float arguments to double before
|
||||
calling the function. */
|
||||
if (TYPE_CODE_FLT == typecode && REGISTER_SIZE == len)
|
||||
{
|
||||
DOUBLEST dblval;
|
||||
dblval = extract_floating (val, len);
|
||||
len = TARGET_DOUBLE_BIT / TARGET_CHAR_BIT;
|
||||
val = alloca (len);
|
||||
store_floating (val, len, dblval);
|
||||
}
|
||||
|
||||
/* If the argument is a pointer to a function, and it is a Thumb
|
||||
function, set the low bit of the pointer. */
|
||||
if (TYPE_CODE_PTR == typecode
|
||||
&& NULL != target_type
|
||||
&& TYPE_CODE_FUNC == TYPE_CODE (target_type))
|
||||
{
|
||||
CORE_ADDR regval = extract_address (val, len);
|
||||
if (arm_pc_is_thumb (regval))
|
||||
store_address (val, len, MAKE_THUMB_ADDR (regval));
|
||||
}
|
||||
|
||||
/* Copy the argument to general registers or the stack in
|
||||
register-sized pieces. Large arguments are split between
|
||||
registers and stack. */
|
||||
while (len > 0)
|
||||
{
|
||||
int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE;
|
||||
|
||||
if (argreg <= ARM_LAST_ARG_REGNUM)
|
||||
{
|
||||
/* It's an argument being passed in a general register. */
|
||||
regval = extract_address (val, partial_len);
|
||||
write_register (argreg++, regval);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Push the arguments onto the stack. */
|
||||
write_memory ((CORE_ADDR) fp, val, REGISTER_SIZE);
|
||||
fp += REGISTER_SIZE;
|
||||
}
|
||||
|
||||
len -= partial_len;
|
||||
val += partial_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return adjusted stack pointer. */
|
||||
return sp;
|
||||
}
|
||||
|
||||
/*
|
||||
Dynamic Linking on ARM Linux
|
||||
----------------------------
|
||||
|
||||
Note: PLT = procedure linkage table
|
||||
GOT = global offset table
|
||||
|
||||
As much as possible, ELF dynamic linking defers the resolution of
|
||||
jump/call addresses until the last minute. The technique used is
|
||||
inspired by the i386 ELF design, and is based on the following
|
||||
constraints.
|
||||
|
||||
1) The calling technique should not force a change in the assembly
|
||||
code produced for apps; it MAY cause changes in the way assembly
|
||||
code is produced for position independent code (i.e. shared
|
||||
libraries).
|
||||
|
||||
2) The technique must be such that all executable areas must not be
|
||||
modified; and any modified areas must not be executed.
|
||||
|
||||
To do this, there are three steps involved in a typical jump:
|
||||
|
||||
1) in the code
|
||||
2) through the PLT
|
||||
3) using a pointer from the GOT
|
||||
|
||||
When the executable or library is first loaded, each GOT entry is
|
||||
initialized to point to the code which implements dynamic name
|
||||
resolution and code finding. This is normally a function in the
|
||||
program interpreter (on ARM Linux this is usually ld-linux.so.2,
|
||||
but it does not have to be). On the first invocation, the function
|
||||
is located and the GOT entry is replaced with the real function
|
||||
address. Subsequent calls go through steps 1, 2 and 3 and end up
|
||||
calling the real code.
|
||||
|
||||
1) In the code:
|
||||
|
||||
b function_call
|
||||
bl function_call
|
||||
|
||||
This is typical ARM code using the 26 bit relative branch or branch
|
||||
and link instructions. The target of the instruction
|
||||
(function_call is usually the address of the function to be called.
|
||||
In position independent code, the target of the instruction is
|
||||
actually an entry in the PLT when calling functions in a shared
|
||||
library. Note that this call is identical to a normal function
|
||||
call, only the target differs.
|
||||
|
||||
2) In the PLT:
|
||||
|
||||
The PLT is a synthetic area, created by the linker. It exists in
|
||||
both executables and libraries. It is an array of stubs, one per
|
||||
imported function call. It looks like this:
|
||||
|
||||
PLT[0]:
|
||||
str lr, [sp, #-4]! @push the return address (lr)
|
||||
ldr lr, [pc, #16] @load from 6 words ahead
|
||||
add lr, pc, lr @form an address for GOT[0]
|
||||
ldr pc, [lr, #8]! @jump to the contents of that addr
|
||||
|
||||
The return address (lr) is pushed on the stack and used for
|
||||
calculations. The load on the second line loads the lr with
|
||||
&GOT[3] - . - 20. The addition on the third leaves:
|
||||
|
||||
lr = (&GOT[3] - . - 20) + (. + 8)
|
||||
lr = (&GOT[3] - 12)
|
||||
lr = &GOT[0]
|
||||
|
||||
On the fourth line, the pc and lr are both updated, so that:
|
||||
|
||||
pc = GOT[2]
|
||||
lr = &GOT[0] + 8
|
||||
= &GOT[2]
|
||||
|
||||
NOTE: PLT[0] borrows an offset .word from PLT[1]. This is a little
|
||||
"tight", but allows us to keep all the PLT entries the same size.
|
||||
|
||||
PLT[n+1]:
|
||||
ldr ip, [pc, #4] @load offset from gotoff
|
||||
add ip, pc, ip @add the offset to the pc
|
||||
ldr pc, [ip] @jump to that address
|
||||
gotoff: .word GOT[n+3] - .
|
||||
|
||||
The load on the first line, gets an offset from the fourth word of
|
||||
the PLT entry. The add on the second line makes ip = &GOT[n+3],
|
||||
which contains either a pointer to PLT[0] (the fixup trampoline) or
|
||||
a pointer to the actual code.
|
||||
|
||||
3) In the GOT:
|
||||
|
||||
The GOT contains helper pointers for both code (PLT) fixups and
|
||||
data fixups. The first 3 entries of the GOT are special. The next
|
||||
M entries (where M is the number of entries in the PLT) belong to
|
||||
the PLT fixups. The next D (all remaining) entries belong to
|
||||
various data fixups. The actual size of the GOT is 3 + M + D.
|
||||
|
||||
The GOT is also a synthetic area, created by the linker. It exists
|
||||
in both executables and libraries. When the GOT is first
|
||||
initialized , all the GOT entries relating to PLT fixups are
|
||||
pointing to code back at PLT[0].
|
||||
|
||||
The special entries in the GOT are:
|
||||
|
||||
GOT[0] = linked list pointer used by the dynamic loader
|
||||
GOT[1] = pointer to the reloc table for this module
|
||||
GOT[2] = pointer to the fixup/resolver code
|
||||
|
||||
The first invocation of function call comes through and uses the
|
||||
fixup/resolver code. On the entry to the fixup/resolver code:
|
||||
|
||||
ip = &GOT[n+3]
|
||||
lr = &GOT[2]
|
||||
stack[0] = return address (lr) of the function call
|
||||
[r0, r1, r2, r3] are still the arguments to the function call
|
||||
|
||||
This is enough information for the fixup/resolver code to work
|
||||
with. Before the fixup/resolver code returns, it actually calls
|
||||
the requested function and repairs &GOT[n+3]. */
|
||||
|
||||
/* Find the minimal symbol named NAME, and return both the minsym
|
||||
struct and its objfile. This probably ought to be in minsym.c, but
|
||||
everything there is trying to deal with things like C++ and
|
||||
SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may
|
||||
be considered too special-purpose for general consumption. */
|
||||
|
||||
static struct minimal_symbol *
|
||||
find_minsym_and_objfile (char *name, struct objfile **objfile_p)
|
||||
{
|
||||
struct objfile *objfile;
|
||||
|
||||
ALL_OBJFILES (objfile)
|
||||
{
|
||||
struct minimal_symbol *msym;
|
||||
|
||||
ALL_OBJFILE_MSYMBOLS (objfile, msym)
|
||||
{
|
||||
if (SYMBOL_NAME (msym)
|
||||
&& STREQ (SYMBOL_NAME (msym), name))
|
||||
{
|
||||
*objfile_p = objfile;
|
||||
return msym;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static CORE_ADDR
|
||||
skip_hurd_resolver (CORE_ADDR pc)
|
||||
{
|
||||
/* The HURD dynamic linker is part of the GNU C library, so many
|
||||
GNU/Linux distributions use it. (All ELF versions, as far as I
|
||||
know.) An unresolved PLT entry points to "_dl_runtime_resolve",
|
||||
which calls "fixup" to patch the PLT, and then passes control to
|
||||
the function.
|
||||
|
||||
We look for the symbol `_dl_runtime_resolve', and find `fixup' in
|
||||
the same objfile. If we are at the entry point of `fixup', then
|
||||
we set a breakpoint at the return address (at the top of the
|
||||
stack), and continue.
|
||||
|
||||
It's kind of gross to do all these checks every time we're
|
||||
called, since they don't change once the executable has gotten
|
||||
started. But this is only a temporary hack --- upcoming versions
|
||||
of Linux will provide a portable, efficient interface for
|
||||
debugging programs that use shared libraries. */
|
||||
|
||||
struct objfile *objfile;
|
||||
struct minimal_symbol *resolver
|
||||
= find_minsym_and_objfile ("_dl_runtime_resolve", &objfile);
|
||||
|
||||
if (resolver)
|
||||
{
|
||||
struct minimal_symbol *fixup
|
||||
= lookup_minimal_symbol ("fixup", NULL, objfile);
|
||||
|
||||
if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
|
||||
return (SAVED_PC_AFTER_CALL (get_current_frame ()));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c.
|
||||
This function:
|
||||
1) decides whether a PLT has sent us into the linker to resolve
|
||||
a function reference, and
|
||||
2) if so, tells us where to set a temporary breakpoint that will
|
||||
trigger when the dynamic linker is done. */
|
||||
|
||||
CORE_ADDR
|
||||
arm_linux_skip_solib_resolver (CORE_ADDR pc)
|
||||
{
|
||||
CORE_ADDR result;
|
||||
|
||||
/* Plug in functions for other kinds of resolvers here. */
|
||||
result = skip_hurd_resolver (pc);
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The constants below were determined by examining the following files
|
||||
in the linux kernel sources:
|
||||
|
||||
arch/arm/kernel/signal.c
|
||||
- see SWI_SYS_SIGRETURN and SWI_SYS_RT_SIGRETURN
|
||||
include/asm-arm/unistd.h
|
||||
- see __NR_sigreturn, __NR_rt_sigreturn, and __NR_SYSCALL_BASE */
|
||||
|
||||
#define ARM_LINUX_SIGRETURN_INSTR 0xef900077
|
||||
#define ARM_LINUX_RT_SIGRETURN_INSTR 0xef9000ad
|
||||
|
||||
/* arm_linux_in_sigtramp determines if PC points at one of the
|
||||
instructions which cause control to return to the Linux kernel upon
|
||||
return from a signal handler. FUNC_NAME is unused. */
|
||||
|
||||
int
|
||||
arm_linux_in_sigtramp (CORE_ADDR pc, char *func_name)
|
||||
{
|
||||
unsigned long inst;
|
||||
|
||||
inst = read_memory_integer (pc, 4);
|
||||
|
||||
return (inst == ARM_LINUX_SIGRETURN_INSTR
|
||||
|| inst == ARM_LINUX_RT_SIGRETURN_INSTR);
|
||||
|
||||
}
|
||||
|
||||
/* arm_linux_sigcontext_register_address returns the address in the
|
||||
sigcontext of register REGNO given a stack pointer value SP and
|
||||
program counter value PC. The value 0 is returned if PC is not
|
||||
pointing at one of the signal return instructions or if REGNO is
|
||||
not saved in the sigcontext struct. */
|
||||
|
||||
CORE_ADDR
|
||||
arm_linux_sigcontext_register_address (CORE_ADDR sp, CORE_ADDR pc, int regno)
|
||||
{
|
||||
unsigned long inst;
|
||||
CORE_ADDR reg_addr = 0;
|
||||
|
||||
inst = read_memory_integer (pc, 4);
|
||||
|
||||
if (inst == ARM_LINUX_SIGRETURN_INSTR || inst == ARM_LINUX_RT_SIGRETURN_INSTR)
|
||||
{
|
||||
CORE_ADDR sigcontext_addr;
|
||||
|
||||
/* The sigcontext structure is at different places for the two
|
||||
signal return instructions. For ARM_LINUX_SIGRETURN_INSTR,
|
||||
it starts at the SP value. For ARM_LINUX_RT_SIGRETURN_INSTR,
|
||||
it is at SP+8. For the latter instruction, it may also be
|
||||
the case that the address of this structure may be determined
|
||||
by reading the 4 bytes at SP, but I'm not convinced this is
|
||||
reliable.
|
||||
|
||||
In any event, these magic constants (0 and 8) may be
|
||||
determined by examining struct sigframe and struct
|
||||
rt_sigframe in arch/arm/kernel/signal.c in the Linux kernel
|
||||
sources. */
|
||||
|
||||
if (inst == ARM_LINUX_RT_SIGRETURN_INSTR)
|
||||
sigcontext_addr = sp + 8;
|
||||
else /* inst == ARM_LINUX_SIGRETURN_INSTR */
|
||||
sigcontext_addr = sp + 0;
|
||||
|
||||
/* The layout of the sigcontext structure for ARM GNU/Linux is
|
||||
in include/asm-arm/sigcontext.h in the Linux kernel sources.
|
||||
|
||||
There are three 4-byte fields which precede the saved r0
|
||||
field. (This accounts for the 12 in the code below.) The
|
||||
sixteen registers (4 bytes per field) follow in order. The
|
||||
PSR value follows the sixteen registers which accounts for
|
||||
the constant 19 below. */
|
||||
|
||||
if (0 <= regno && regno <= PC_REGNUM)
|
||||
reg_addr = sigcontext_addr + 12 + (4 * regno);
|
||||
else if (regno == PS_REGNUM)
|
||||
reg_addr = sigcontext_addr + 19 * 4;
|
||||
}
|
||||
|
||||
return reg_addr;
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_arm_linux_tdep (void)
|
||||
{
|
||||
}
|
||||
2452
gdb/arm-tdep.c
2452
gdb/arm-tdep.c
File diff suppressed because it is too large
Load Diff
@@ -1,98 +0,0 @@
|
||||
/* Native-dependent code for BSD Unix running on ARM's, for GDB.
|
||||
Copyright 1988, 1989, 1991, 1992, 1994, 1996, 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#ifdef FETCH_INFERIOR_REGISTERS
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/frame.h>
|
||||
#include "inferior.h"
|
||||
|
||||
void
|
||||
fetch_inferior_registers (regno)
|
||||
int regno;
|
||||
{
|
||||
struct reg inferior_registers;
|
||||
struct fpreg inferior_fpregisters;
|
||||
|
||||
ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &inferior_registers, 0);
|
||||
memcpy (®isters[REGISTER_BYTE (0)], &inferior_registers,
|
||||
16 * sizeof (unsigned int));
|
||||
memcpy (®isters[REGISTER_BYTE (PS_REGNUM)], &inferior_registers.r_cpsr,
|
||||
sizeof (unsigned int));
|
||||
ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &inferior_fpregisters, 0);
|
||||
memcpy (®isters[REGISTER_BYTE (F0_REGNUM)], &inferior_fpregisters.fpr[0],
|
||||
8 * sizeof (fp_reg_t));
|
||||
memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)],
|
||||
&inferior_fpregisters.fpr_fpsr, sizeof (unsigned int));
|
||||
registers_fetched ();
|
||||
}
|
||||
|
||||
void
|
||||
store_inferior_registers (regno)
|
||||
int regno;
|
||||
{
|
||||
struct reg inferior_registers;
|
||||
|
||||
memcpy (&inferior_registers, ®isters[REGISTER_BYTE (0)],
|
||||
16 * sizeof (unsigned int));
|
||||
memcpy (&inferior_registers.r_cpsr, ®isters[REGISTER_BYTE (PS_REGNUM)],
|
||||
sizeof (unsigned int));
|
||||
ptrace (PT_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &inferior_registers, 0);
|
||||
|
||||
/* XXX Set FP regs. */
|
||||
}
|
||||
|
||||
struct md_core
|
||||
{
|
||||
struct reg intreg;
|
||||
struct fpreg freg;
|
||||
};
|
||||
|
||||
void
|
||||
fetch_core_registers (core_reg_sect, core_reg_size, which, ignore)
|
||||
char *core_reg_sect;
|
||||
unsigned core_reg_size;
|
||||
int which;
|
||||
CORE_ADDR ignore;
|
||||
{
|
||||
struct md_core *core_reg = (struct md_core *) core_reg_sect;
|
||||
|
||||
/* integer registers */
|
||||
memcpy (®isters[REGISTER_BYTE (0)], &core_reg->intreg,
|
||||
sizeof (struct reg));
|
||||
/* floating point registers */
|
||||
/* XXX */
|
||||
}
|
||||
|
||||
#else
|
||||
#error Not FETCH_INFERIOR_REGISTERS
|
||||
#endif /* !FETCH_INFERIOR_REGISTERS */
|
||||
|
||||
int
|
||||
get_longjmp_target (CORE_ADDR *addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
1859
gdb/ax-gdb.c
1859
gdb/ax-gdb.c
File diff suppressed because it is too large
Load Diff
112
gdb/ax-gdb.h
112
gdb/ax-gdb.h
@@ -1,112 +0,0 @@
|
||||
/* GDB-specific functions for operating on agent expressions
|
||||
Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef AX_GDB_H
|
||||
#define AX_GDB_H
|
||||
|
||||
|
||||
/* Types and enums */
|
||||
|
||||
/* GDB stores expressions in the form of a flattened tree (struct
|
||||
expression), so we just walk that tree and generate agent bytecodes
|
||||
as we go along.
|
||||
|
||||
GDB's normal evaluation uses struct value, which contains the
|
||||
expression's value as well as its address or the register it came
|
||||
from. The `+' operator uses the value, whereas the unary `&'
|
||||
operator will use the address portion. The `=' operator will use
|
||||
the address or register number of its left hand side.
|
||||
|
||||
The issues are different when generating agent bytecode. Given a
|
||||
variable reference expression, we should not necessarily generate
|
||||
code to fetch its value, because the next operator may be `=' or
|
||||
unary `&'. Instead, when we recurse on a subexpression, we
|
||||
indicate whether we want that expression to produce an lvalue or an
|
||||
rvalue. If we requested an lvalue, then the recursive call tells
|
||||
us whether it generated code to compute an address on the stack, or
|
||||
whether the lvalue lives in a register.
|
||||
|
||||
The `axs' prefix here means `agent expression, static', because
|
||||
this is all static analysis of the expression, i.e. analysis which
|
||||
doesn't depend on the contents of memory and registers. */
|
||||
|
||||
|
||||
/* Different kinds of agent expression static values. */
|
||||
enum axs_lvalue_kind
|
||||
{
|
||||
/* We generated code to compute the subexpression's value.
|
||||
Constants and arithmetic operators yield this. */
|
||||
axs_rvalue,
|
||||
|
||||
/* We generated code to yield the subexpression's value's address on
|
||||
the top of the stack. If the caller needs an rvalue, it should
|
||||
call require_rvalue to produce the rvalue from this address. */
|
||||
axs_lvalue_memory,
|
||||
|
||||
/* We didn't generate any code, and the stack is undisturbed,
|
||||
because the subexpression's value lives in a register; u.reg is
|
||||
the register number. If the caller needs an rvalue, it should
|
||||
call require_rvalue to produce the rvalue from this register
|
||||
number. */
|
||||
axs_lvalue_register
|
||||
};
|
||||
|
||||
/* Structure describing what we got from a subexpression. Think of
|
||||
this as parallel to value.h's enum lval_type, except that we're
|
||||
describing a value which will exist when the expression is
|
||||
evaluated in the future, not a value we have in our hand. */
|
||||
struct axs_value
|
||||
{
|
||||
enum axs_lvalue_kind kind; /* see above */
|
||||
|
||||
/* The type of the subexpression. Even if lvalue == axs_lvalue_memory,
|
||||
this is the type of the value itself; the value on the stack is a
|
||||
"pointer to" an object of this type. */
|
||||
struct type *type;
|
||||
|
||||
union
|
||||
{
|
||||
/* if kind == axs_lvalue_register, this is the register number */
|
||||
int reg;
|
||||
}
|
||||
u;
|
||||
};
|
||||
|
||||
|
||||
/* Translating GDB expressions into agent expressions. */
|
||||
|
||||
/* Given a GDB expression EXPR, translate it into the agent bytecode,
|
||||
and return it. FLAGS are from enum expr_to_agent_flags. */
|
||||
extern struct agent_expr *expr_to_agent (struct expression *EXPR,
|
||||
struct axs_value *VALUE);
|
||||
|
||||
/* Given a GDB expression EXPR denoting an lvalue in memory, produce a
|
||||
string of agent bytecode which will leave its address and size on
|
||||
the top of stack. Return the agent expression. */
|
||||
extern struct agent_expr *expr_to_address_and_size (struct expression *EXPR);
|
||||
|
||||
/* Given a GDB expression EXPR, return bytecode to trace its value.
|
||||
The result will use the `trace' and `trace_quick' bytecodes to
|
||||
record the value of all memory touched by the expression, and leave
|
||||
no values on the stack. The caller can then use the ax_reqs
|
||||
function to discover which registers the expression uses. */
|
||||
extern struct agent_expr *gen_trace_for_expr (CORE_ADDR, struct expression *);
|
||||
|
||||
#endif /* AX_GDB_H */
|
||||
541
gdb/ax-general.c
541
gdb/ax-general.c
@@ -1,541 +0,0 @@
|
||||
/* Functions for manipulating expressions designed to be executed on the agent
|
||||
Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Despite what the above comment says about this file being part of
|
||||
GDB, we would like to keep these functions free of GDB
|
||||
dependencies, since we want to be able to use them in contexts
|
||||
outside of GDB (test suites, the stub, etc.) */
|
||||
|
||||
#include "defs.h"
|
||||
#include "ax.h"
|
||||
|
||||
#include "value.h"
|
||||
|
||||
static void grow_expr (struct agent_expr *x, int n);
|
||||
|
||||
static void append_const (struct agent_expr *x, LONGEST val, int n);
|
||||
|
||||
static LONGEST read_const (struct agent_expr *x, int o, int n);
|
||||
|
||||
static void generic_ext (struct agent_expr *x, enum agent_op op, int n);
|
||||
|
||||
/* Functions for building expressions. */
|
||||
|
||||
/* Allocate a new, empty agent expression. */
|
||||
struct agent_expr *
|
||||
new_agent_expr (CORE_ADDR scope)
|
||||
{
|
||||
struct agent_expr *x = xmalloc (sizeof (*x));
|
||||
x->len = 0;
|
||||
x->size = 1; /* Change this to a larger value once
|
||||
reallocation code is tested. */
|
||||
x->buf = xmalloc (x->size);
|
||||
x->scope = scope;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Free a agent expression. */
|
||||
void
|
||||
free_agent_expr (struct agent_expr *x)
|
||||
{
|
||||
xfree (x->buf);
|
||||
xfree (x);
|
||||
}
|
||||
|
||||
static void
|
||||
do_free_agent_expr_cleanup (void *x)
|
||||
{
|
||||
free_agent_expr (x);
|
||||
}
|
||||
|
||||
struct cleanup *
|
||||
make_cleanup_free_agent_expr (struct agent_expr *x)
|
||||
{
|
||||
return make_cleanup (do_free_agent_expr_cleanup, x);
|
||||
}
|
||||
|
||||
|
||||
/* Make sure that X has room for at least N more bytes. This doesn't
|
||||
affect the length, just the allocated size. */
|
||||
static void
|
||||
grow_expr (struct agent_expr *x, int n)
|
||||
{
|
||||
if (x->len + n > x->size)
|
||||
{
|
||||
x->size *= 2;
|
||||
if (x->size < x->len + n)
|
||||
x->size = x->len + n + 10;
|
||||
x->buf = xrealloc (x->buf, x->size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Append the low N bytes of VAL as an N-byte integer to the
|
||||
expression X, in big-endian order. */
|
||||
static void
|
||||
append_const (struct agent_expr *x, LONGEST val, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
grow_expr (x, n);
|
||||
for (i = n - 1; i >= 0; i--)
|
||||
{
|
||||
x->buf[x->len + i] = val & 0xff;
|
||||
val >>= 8;
|
||||
}
|
||||
x->len += n;
|
||||
}
|
||||
|
||||
|
||||
/* Extract an N-byte big-endian unsigned integer from expression X at
|
||||
offset O. */
|
||||
static LONGEST
|
||||
read_const (struct agent_expr *x, int o, int n)
|
||||
{
|
||||
int i;
|
||||
LONGEST accum = 0;
|
||||
|
||||
/* Make sure we're not reading off the end of the expression. */
|
||||
if (o + n > x->len)
|
||||
error ("GDB bug: ax-general.c (read_const): incomplete constant");
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
accum = (accum << 8) | x->buf[o + i];
|
||||
|
||||
return accum;
|
||||
}
|
||||
|
||||
|
||||
/* Append a simple operator OP to EXPR. */
|
||||
void
|
||||
ax_simple (struct agent_expr *x, enum agent_op op)
|
||||
{
|
||||
grow_expr (x, 1);
|
||||
x->buf[x->len++] = op;
|
||||
}
|
||||
|
||||
|
||||
/* Append a sign-extension or zero-extension instruction to EXPR, to
|
||||
extend an N-bit value. */
|
||||
static void
|
||||
generic_ext (struct agent_expr *x, enum agent_op op, int n)
|
||||
{
|
||||
/* N must fit in a byte. */
|
||||
if (n < 0 || n > 255)
|
||||
error ("GDB bug: ax-general.c (generic_ext): bit count out of range");
|
||||
/* That had better be enough range. */
|
||||
if (sizeof (LONGEST) * 8 > 255)
|
||||
error ("GDB bug: ax-general.c (generic_ext): opcode has inadequate range");
|
||||
|
||||
grow_expr (x, 2);
|
||||
x->buf[x->len++] = op;
|
||||
x->buf[x->len++] = n;
|
||||
}
|
||||
|
||||
|
||||
/* Append a sign-extension instruction to EXPR, to extend an N-bit value. */
|
||||
void
|
||||
ax_ext (struct agent_expr *x, int n)
|
||||
{
|
||||
generic_ext (x, aop_ext, n);
|
||||
}
|
||||
|
||||
|
||||
/* Append a zero-extension instruction to EXPR, to extend an N-bit value. */
|
||||
void
|
||||
ax_zero_ext (struct agent_expr *x, int n)
|
||||
{
|
||||
generic_ext (x, aop_zero_ext, n);
|
||||
}
|
||||
|
||||
|
||||
/* Append a trace_quick instruction to EXPR, to record N bytes. */
|
||||
void
|
||||
ax_trace_quick (struct agent_expr *x, int n)
|
||||
{
|
||||
/* N must fit in a byte. */
|
||||
if (n < 0 || n > 255)
|
||||
error ("GDB bug: ax-general.c (ax_trace_quick): size out of range for trace_quick");
|
||||
|
||||
grow_expr (x, 2);
|
||||
x->buf[x->len++] = aop_trace_quick;
|
||||
x->buf[x->len++] = n;
|
||||
}
|
||||
|
||||
|
||||
/* Append a goto op to EXPR. OP is the actual op (must be aop_goto or
|
||||
aop_if_goto). We assume we don't know the target offset yet,
|
||||
because it's probably a forward branch, so we leave space in EXPR
|
||||
for the target, and return the offset in EXPR of that space, so we
|
||||
can backpatch it once we do know the target offset. Use ax_label
|
||||
to do the backpatching. */
|
||||
int
|
||||
ax_goto (struct agent_expr *x, enum agent_op op)
|
||||
{
|
||||
grow_expr (x, 3);
|
||||
x->buf[x->len + 0] = op;
|
||||
x->buf[x->len + 1] = 0xff;
|
||||
x->buf[x->len + 2] = 0xff;
|
||||
x->len += 3;
|
||||
return x->len - 2;
|
||||
}
|
||||
|
||||
/* Suppose a given call to ax_goto returns some value PATCH. When you
|
||||
know the offset TARGET that goto should jump to, call
|
||||
ax_label (EXPR, PATCH, TARGET)
|
||||
to patch TARGET into the ax_goto instruction. */
|
||||
void
|
||||
ax_label (struct agent_expr *x, int patch, int target)
|
||||
{
|
||||
/* Make sure the value is in range. Don't accept 0xffff as an
|
||||
offset; that's our magic sentinel value for unpatched branches. */
|
||||
if (target < 0 || target >= 0xffff)
|
||||
error ("GDB bug: ax-general.c (ax_label): label target out of range");
|
||||
|
||||
x->buf[patch] = (target >> 8) & 0xff;
|
||||
x->buf[patch + 1] = target & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/* Assemble code to push a constant on the stack. */
|
||||
void
|
||||
ax_const_l (struct agent_expr *x, LONGEST l)
|
||||
{
|
||||
static enum agent_op ops[]
|
||||
=
|
||||
{aop_const8, aop_const16, aop_const32, aop_const64};
|
||||
int size;
|
||||
int op;
|
||||
|
||||
/* How big is the number? 'op' keeps track of which opcode to use.
|
||||
Notice that we don't really care whether the original number was
|
||||
signed or unsigned; we always reproduce the value exactly, and
|
||||
use the shortest representation. */
|
||||
for (op = 0, size = 8; size < 64; size *= 2, op++)
|
||||
if (-((LONGEST) 1 << size) <= l && l < ((LONGEST) 1 << size))
|
||||
break;
|
||||
|
||||
/* Emit the right opcode... */
|
||||
ax_simple (x, ops[op]);
|
||||
|
||||
/* Emit the low SIZE bytes as an unsigned number. We know that
|
||||
sign-extending this will yield l. */
|
||||
append_const (x, l, size / 8);
|
||||
|
||||
/* Now, if it was negative, and not full-sized, sign-extend it. */
|
||||
if (l < 0 && size < 64)
|
||||
ax_ext (x, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ax_const_d (struct agent_expr *x, LONGEST d)
|
||||
{
|
||||
/* FIXME: floating-point support not present yet. */
|
||||
error ("GDB bug: ax-general.c (ax_const_d): floating point not supported yet");
|
||||
}
|
||||
|
||||
|
||||
/* Assemble code to push the value of register number REG on the
|
||||
stack. */
|
||||
void
|
||||
ax_reg (struct agent_expr *x, int reg)
|
||||
{
|
||||
/* Make sure the register number is in range. */
|
||||
if (reg < 0 || reg > 0xffff)
|
||||
error ("GDB bug: ax-general.c (ax_reg): register number out of range");
|
||||
grow_expr (x, 3);
|
||||
x->buf[x->len] = aop_reg;
|
||||
x->buf[x->len + 1] = (reg >> 8) & 0xff;
|
||||
x->buf[x->len + 2] = (reg) & 0xff;
|
||||
x->len += 3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Functions for disassembling agent expressions, and otherwise
|
||||
debugging the expression compiler. */
|
||||
|
||||
struct aop_map aop_map[] =
|
||||
{
|
||||
{0, 0, 0, 0, 0},
|
||||
{"float", 0, 0, 0, 0}, /* 0x01 */
|
||||
{"add", 0, 0, 2, 1}, /* 0x02 */
|
||||
{"sub", 0, 0, 2, 1}, /* 0x03 */
|
||||
{"mul", 0, 0, 2, 1}, /* 0x04 */
|
||||
{"div_signed", 0, 0, 2, 1}, /* 0x05 */
|
||||
{"div_unsigned", 0, 0, 2, 1}, /* 0x06 */
|
||||
{"rem_signed", 0, 0, 2, 1}, /* 0x07 */
|
||||
{"rem_unsigned", 0, 0, 2, 1}, /* 0x08 */
|
||||
{"lsh", 0, 0, 2, 1}, /* 0x09 */
|
||||
{"rsh_signed", 0, 0, 2, 1}, /* 0x0a */
|
||||
{"rsh_unsigned", 0, 0, 2, 1}, /* 0x0b */
|
||||
{"trace", 0, 0, 2, 0}, /* 0x0c */
|
||||
{"trace_quick", 1, 0, 1, 1}, /* 0x0d */
|
||||
{"log_not", 0, 0, 1, 1}, /* 0x0e */
|
||||
{"bit_and", 0, 0, 2, 1}, /* 0x0f */
|
||||
{"bit_or", 0, 0, 2, 1}, /* 0x10 */
|
||||
{"bit_xor", 0, 0, 2, 1}, /* 0x11 */
|
||||
{"bit_not", 0, 0, 1, 1}, /* 0x12 */
|
||||
{"equal", 0, 0, 2, 1}, /* 0x13 */
|
||||
{"less_signed", 0, 0, 2, 1}, /* 0x14 */
|
||||
{"less_unsigned", 0, 0, 2, 1}, /* 0x15 */
|
||||
{"ext", 1, 0, 1, 1}, /* 0x16 */
|
||||
{"ref8", 0, 8, 1, 1}, /* 0x17 */
|
||||
{"ref16", 0, 16, 1, 1}, /* 0x18 */
|
||||
{"ref32", 0, 32, 1, 1}, /* 0x19 */
|
||||
{"ref64", 0, 64, 1, 1}, /* 0x1a */
|
||||
{"ref_float", 0, 0, 1, 1}, /* 0x1b */
|
||||
{"ref_double", 0, 0, 1, 1}, /* 0x1c */
|
||||
{"ref_long_double", 0, 0, 1, 1}, /* 0x1d */
|
||||
{"l_to_d", 0, 0, 1, 1}, /* 0x1e */
|
||||
{"d_to_l", 0, 0, 1, 1}, /* 0x1f */
|
||||
{"if_goto", 2, 0, 1, 0}, /* 0x20 */
|
||||
{"goto", 2, 0, 0, 0}, /* 0x21 */
|
||||
{"const8", 1, 8, 0, 1}, /* 0x22 */
|
||||
{"const16", 2, 16, 0, 1}, /* 0x23 */
|
||||
{"const32", 4, 32, 0, 1}, /* 0x24 */
|
||||
{"const64", 8, 64, 0, 1}, /* 0x25 */
|
||||
{"reg", 2, 0, 0, 1}, /* 0x26 */
|
||||
{"end", 0, 0, 0, 0}, /* 0x27 */
|
||||
{"dup", 0, 0, 1, 2}, /* 0x28 */
|
||||
{"pop", 0, 0, 1, 0}, /* 0x29 */
|
||||
{"zero_ext", 1, 0, 1, 1}, /* 0x2a */
|
||||
{"swap", 0, 0, 2, 2}, /* 0x2b */
|
||||
{0, 0, 0, 0, 0}, /* 0x2c */
|
||||
{0, 0, 0, 0, 0}, /* 0x2d */
|
||||
{0, 0, 0, 0, 0}, /* 0x2e */
|
||||
{0, 0, 0, 0, 0}, /* 0x2f */
|
||||
{"trace16", 2, 0, 1, 1}, /* 0x30 */
|
||||
};
|
||||
|
||||
|
||||
/* Disassemble the expression EXPR, writing to F. */
|
||||
void
|
||||
ax_print (struct ui_file *f, struct agent_expr *x)
|
||||
{
|
||||
int i;
|
||||
int is_float = 0;
|
||||
|
||||
/* Check the size of the name array against the number of entries in
|
||||
the enum, to catch additions that people didn't sync. */
|
||||
if ((sizeof (aop_map) / sizeof (aop_map[0]))
|
||||
!= aop_last)
|
||||
error ("GDB bug: ax-general.c (ax_print): opcode map out of sync");
|
||||
|
||||
for (i = 0; i < x->len;)
|
||||
{
|
||||
enum agent_op op = x->buf[i];
|
||||
|
||||
if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
|
||||
|| !aop_map[op].name)
|
||||
{
|
||||
fprintf_filtered (f, "%3d <bad opcode %02x>\n", i, op);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (i + 1 + aop_map[op].op_size > x->len)
|
||||
{
|
||||
fprintf_filtered (f, "%3d <incomplete opcode %s>\n",
|
||||
i, aop_map[op].name);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf_filtered (f, "%3d %s", i, aop_map[op].name);
|
||||
if (aop_map[op].op_size > 0)
|
||||
{
|
||||
fputs_filtered (" ", f);
|
||||
|
||||
print_longest (f, 'd', 0,
|
||||
read_const (x, i + 1, aop_map[op].op_size));
|
||||
}
|
||||
fprintf_filtered (f, "\n");
|
||||
i += 1 + aop_map[op].op_size;
|
||||
|
||||
is_float = (op == aop_float);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Given an agent expression AX, fill in an agent_reqs structure REQS
|
||||
describing it. */
|
||||
void
|
||||
ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs)
|
||||
{
|
||||
int i;
|
||||
int height;
|
||||
|
||||
/* Bit vector for registers used. */
|
||||
int reg_mask_len = 1;
|
||||
unsigned char *reg_mask = xmalloc (reg_mask_len * sizeof (reg_mask[0]));
|
||||
|
||||
/* Jump target table. targets[i] is non-zero iff there is a jump to
|
||||
offset i. */
|
||||
char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
|
||||
|
||||
/* Instruction boundary table. boundary[i] is non-zero iff an
|
||||
instruction starts at offset i. */
|
||||
char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));
|
||||
|
||||
/* Stack height record. iff either targets[i] or boundary[i] is
|
||||
non-zero, heights[i] is the height the stack should have before
|
||||
executing the bytecode at that point. */
|
||||
int *heights = (int *) alloca (ax->len * sizeof (heights[0]));
|
||||
|
||||
/* Pointer to a description of the present op. */
|
||||
struct aop_map *op;
|
||||
|
||||
memset (reg_mask, 0, reg_mask_len * sizeof (reg_mask[0]));
|
||||
memset (targets, 0, ax->len * sizeof (targets[0]));
|
||||
memset (boundary, 0, ax->len * sizeof (boundary[0]));
|
||||
|
||||
reqs->max_height = reqs->min_height = height = 0;
|
||||
reqs->flaw = agent_flaw_none;
|
||||
reqs->max_data_size = 0;
|
||||
|
||||
for (i = 0; i < ax->len; i += 1 + op->op_size)
|
||||
{
|
||||
if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
|
||||
{
|
||||
reqs->flaw = agent_flaw_bad_instruction;
|
||||
xfree (reg_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
op = &aop_map[ax->buf[i]];
|
||||
|
||||
if (!op->name)
|
||||
{
|
||||
reqs->flaw = agent_flaw_bad_instruction;
|
||||
xfree (reg_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
if (i + 1 + op->op_size > ax->len)
|
||||
{
|
||||
reqs->flaw = agent_flaw_incomplete_instruction;
|
||||
xfree (reg_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this instruction is a jump target, does the current stack
|
||||
height match the stack height at the jump source? */
|
||||
if (targets[i] && (heights[i] != height))
|
||||
{
|
||||
reqs->flaw = agent_flaw_height_mismatch;
|
||||
xfree (reg_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
boundary[i] = 1;
|
||||
heights[i] = height;
|
||||
|
||||
height -= op->consumed;
|
||||
if (height < reqs->min_height)
|
||||
reqs->min_height = height;
|
||||
height += op->produced;
|
||||
if (height > reqs->max_height)
|
||||
reqs->max_height = height;
|
||||
|
||||
if (op->data_size > reqs->max_data_size)
|
||||
reqs->max_data_size = op->data_size;
|
||||
|
||||
/* For jump instructions, check that the target is a valid
|
||||
offset. If it is, record the fact that that location is a
|
||||
jump target, and record the height we expect there. */
|
||||
if (aop_goto == op - aop_map
|
||||
|| aop_if_goto == op - aop_map)
|
||||
{
|
||||
int target = read_const (ax, i + 1, 2);
|
||||
if (target < 0 || target >= ax->len)
|
||||
{
|
||||
reqs->flaw = agent_flaw_bad_jump;
|
||||
xfree (reg_mask);
|
||||
return;
|
||||
}
|
||||
/* Have we already found other jumps to the same location? */
|
||||
else if (targets[target])
|
||||
{
|
||||
if (heights[i] != height)
|
||||
{
|
||||
reqs->flaw = agent_flaw_height_mismatch;
|
||||
xfree (reg_mask);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targets[target] = 1;
|
||||
heights[target] = height;
|
||||
}
|
||||
}
|
||||
|
||||
/* For unconditional jumps with a successor, check that the
|
||||
successor is a target, and pick up its stack height. */
|
||||
if (aop_goto == op - aop_map
|
||||
&& i + 3 < ax->len)
|
||||
{
|
||||
if (!targets[i + 3])
|
||||
{
|
||||
reqs->flaw = agent_flaw_hole;
|
||||
xfree (reg_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
height = heights[i + 3];
|
||||
}
|
||||
|
||||
/* For reg instructions, record the register in the bit mask. */
|
||||
if (aop_reg == op - aop_map)
|
||||
{
|
||||
int reg = read_const (ax, i + 1, 2);
|
||||
int byte = reg / 8;
|
||||
|
||||
/* Grow the bit mask if necessary. */
|
||||
if (byte >= reg_mask_len)
|
||||
{
|
||||
/* It's not appropriate to double here. This isn't a
|
||||
string buffer. */
|
||||
int new_len = byte + 1;
|
||||
reg_mask = xrealloc (reg_mask,
|
||||
new_len * sizeof (reg_mask[0]));
|
||||
memset (reg_mask + reg_mask_len, 0,
|
||||
(new_len - reg_mask_len) * sizeof (reg_mask[0]));
|
||||
reg_mask_len = new_len;
|
||||
}
|
||||
|
||||
reg_mask[byte] |= 1 << (reg % 8);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that all the targets are on boundaries. */
|
||||
for (i = 0; i < ax->len; i++)
|
||||
if (targets[i] && !boundary[i])
|
||||
{
|
||||
reqs->flaw = agent_flaw_bad_jump;
|
||||
xfree (reg_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
reqs->final_height = height;
|
||||
reqs->reg_mask_len = reg_mask_len;
|
||||
reqs->reg_mask = reg_mask;
|
||||
}
|
||||
292
gdb/ax.h
292
gdb/ax.h
@@ -1,292 +0,0 @@
|
||||
/* Definitions for expressions designed to be executed on the agent
|
||||
Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef AGENTEXPR_H
|
||||
#define AGENTEXPR_H
|
||||
|
||||
#include "doublest.h" /* For DOUBLEST. */
|
||||
|
||||
/* It's sometimes useful to be able to debug programs that you can't
|
||||
really stop for more than a fraction of a second. To this end, the
|
||||
user can specify a tracepoint (like a breakpoint, but you don't
|
||||
stop at it), and specify a bunch of expressions to record the
|
||||
values of when that tracepoint is reached. As the program runs,
|
||||
GDB collects the values. At any point (possibly while values are
|
||||
still being collected), the user can display the collected values.
|
||||
|
||||
This is used with remote debugging; we don't really support it on
|
||||
native configurations.
|
||||
|
||||
This means that expressions are being evaluated by the remote agent,
|
||||
which doesn't have any access to the symbol table information, and
|
||||
needs to be small and simple.
|
||||
|
||||
The agent_expr routines and datatypes are a bytecode language
|
||||
designed to be executed by the agent. Agent expressions work in
|
||||
terms of fixed-width values, operators, memory references, and
|
||||
register references. You can evaluate a agent expression just given
|
||||
a bunch of memory and register values to sniff at; you don't need
|
||||
any symbolic information like variable names, types, etc.
|
||||
|
||||
GDB translates source expressions, whose meaning depends on
|
||||
symbolic information, into agent bytecode expressions, whose meaning
|
||||
is independent of symbolic information. This means the agent can
|
||||
evaluate them on the fly without reference to data only available
|
||||
to the host GDB. */
|
||||
|
||||
|
||||
/* Agent expression data structures. */
|
||||
|
||||
/* The type of an element of the agent expression stack.
|
||||
The bytecode operation indicates which element we should access;
|
||||
the value itself has no typing information. GDB generates all
|
||||
bytecode streams, so we don't have to worry about type errors. */
|
||||
|
||||
union agent_val
|
||||
{
|
||||
LONGEST l;
|
||||
DOUBLEST d;
|
||||
};
|
||||
|
||||
/* A buffer containing a agent expression. */
|
||||
struct agent_expr
|
||||
{
|
||||
unsigned char *buf;
|
||||
int len; /* number of characters used */
|
||||
int size; /* allocated size */
|
||||
CORE_ADDR scope;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* The actual values of the various bytecode operations.
|
||||
|
||||
Other independent implementations of the agent bytecode engine will
|
||||
rely on the exact values of these enums, and may not be recompiled
|
||||
when we change this table. The numeric values should remain fixed
|
||||
whenever possible. Thus, we assign them values explicitly here (to
|
||||
allow gaps to form safely), and the disassembly table in
|
||||
agentexpr.h behaves like an opcode map. If you want to see them
|
||||
grouped logically, see doc/agentexpr.texi. */
|
||||
|
||||
enum agent_op
|
||||
{
|
||||
aop_float = 0x01,
|
||||
aop_add = 0x02,
|
||||
aop_sub = 0x03,
|
||||
aop_mul = 0x04,
|
||||
aop_div_signed = 0x05,
|
||||
aop_div_unsigned = 0x06,
|
||||
aop_rem_signed = 0x07,
|
||||
aop_rem_unsigned = 0x08,
|
||||
aop_lsh = 0x09,
|
||||
aop_rsh_signed = 0x0a,
|
||||
aop_rsh_unsigned = 0x0b,
|
||||
aop_trace = 0x0c,
|
||||
aop_trace_quick = 0x0d,
|
||||
aop_log_not = 0x0e,
|
||||
aop_bit_and = 0x0f,
|
||||
aop_bit_or = 0x10,
|
||||
aop_bit_xor = 0x11,
|
||||
aop_bit_not = 0x12,
|
||||
aop_equal = 0x13,
|
||||
aop_less_signed = 0x14,
|
||||
aop_less_unsigned = 0x15,
|
||||
aop_ext = 0x16,
|
||||
aop_ref8 = 0x17,
|
||||
aop_ref16 = 0x18,
|
||||
aop_ref32 = 0x19,
|
||||
aop_ref64 = 0x1a,
|
||||
aop_ref_float = 0x1b,
|
||||
aop_ref_double = 0x1c,
|
||||
aop_ref_long_double = 0x1d,
|
||||
aop_l_to_d = 0x1e,
|
||||
aop_d_to_l = 0x1f,
|
||||
aop_if_goto = 0x20,
|
||||
aop_goto = 0x21,
|
||||
aop_const8 = 0x22,
|
||||
aop_const16 = 0x23,
|
||||
aop_const32 = 0x24,
|
||||
aop_const64 = 0x25,
|
||||
aop_reg = 0x26,
|
||||
aop_end = 0x27,
|
||||
aop_dup = 0x28,
|
||||
aop_pop = 0x29,
|
||||
aop_zero_ext = 0x2a,
|
||||
aop_swap = 0x2b,
|
||||
aop_trace16 = 0x30,
|
||||
aop_last
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Functions for building expressions. */
|
||||
|
||||
/* Allocate a new, empty agent expression. */
|
||||
extern struct agent_expr *new_agent_expr (CORE_ADDR);
|
||||
|
||||
/* Free a agent expression. */
|
||||
extern void free_agent_expr (struct agent_expr *);
|
||||
extern struct cleanup *make_cleanup_free_agent_expr (struct agent_expr *);
|
||||
|
||||
/* Append a simple operator OP to EXPR. */
|
||||
extern void ax_simple (struct agent_expr *EXPR, enum agent_op OP);
|
||||
|
||||
/* Append the floating-point prefix, for the next bytecode. */
|
||||
#define ax_float(EXPR) (ax_simple ((EXPR), aop_float))
|
||||
|
||||
/* Append a sign-extension instruction to EXPR, to extend an N-bit value. */
|
||||
extern void ax_ext (struct agent_expr *EXPR, int N);
|
||||
|
||||
/* Append a zero-extension instruction to EXPR, to extend an N-bit value. */
|
||||
extern void ax_zero_ext (struct agent_expr *EXPR, int N);
|
||||
|
||||
/* Append a trace_quick instruction to EXPR, to record N bytes. */
|
||||
extern void ax_trace_quick (struct agent_expr *EXPR, int N);
|
||||
|
||||
/* Append a goto op to EXPR. OP is the actual op (must be aop_goto or
|
||||
aop_if_goto). We assume we don't know the target offset yet,
|
||||
because it's probably a forward branch, so we leave space in EXPR
|
||||
for the target, and return the offset in EXPR of that space, so we
|
||||
can backpatch it once we do know the target offset. Use ax_label
|
||||
to do the backpatching. */
|
||||
extern int ax_goto (struct agent_expr *EXPR, enum agent_op OP);
|
||||
|
||||
/* Suppose a given call to ax_goto returns some value PATCH. When you
|
||||
know the offset TARGET that goto should jump to, call
|
||||
ax_label (EXPR, PATCH, TARGET)
|
||||
to patch TARGET into the ax_goto instruction. */
|
||||
extern void ax_label (struct agent_expr *EXPR, int patch, int target);
|
||||
|
||||
/* Assemble code to push a constant on the stack. */
|
||||
extern void ax_const_l (struct agent_expr *EXPR, LONGEST l);
|
||||
extern void ax_const_d (struct agent_expr *EXPR, LONGEST d);
|
||||
|
||||
/* Assemble code to push the value of register number REG on the
|
||||
stack. */
|
||||
extern void ax_reg (struct agent_expr *EXPR, int REG);
|
||||
|
||||
|
||||
/* Functions for printing out expressions, and otherwise debugging
|
||||
things. */
|
||||
|
||||
/* Disassemble the expression EXPR, writing to F. */
|
||||
extern void ax_print (struct ui_file *f, struct agent_expr * EXPR);
|
||||
|
||||
/* An entry in the opcode map. */
|
||||
struct aop_map
|
||||
{
|
||||
|
||||
/* The name of the opcode. Null means that this entry is not a
|
||||
valid opcode --- a hole in the opcode space. */
|
||||
char *name;
|
||||
|
||||
/* All opcodes take no operands from the bytecode stream, or take
|
||||
unsigned integers of various sizes. If this is a positive number
|
||||
n, then the opcode is followed by an n-byte operand, which should
|
||||
be printed as an unsigned integer. If this is zero, then the
|
||||
opcode takes no operands from the bytecode stream.
|
||||
|
||||
If we get more complicated opcodes in the future, don't add other
|
||||
magic values of this; that's a crock. Add an `enum encoding'
|
||||
field to this, or something like that. */
|
||||
int op_size;
|
||||
|
||||
/* The size of the data operated upon, in bits, for bytecodes that
|
||||
care about that (ref and const). Zero for all others. */
|
||||
int data_size;
|
||||
|
||||
/* Number of stack elements consumed, and number produced. */
|
||||
int consumed, produced;
|
||||
};
|
||||
|
||||
/* Map of the bytecodes, indexed by bytecode number. */
|
||||
extern struct aop_map aop_map[];
|
||||
|
||||
/* Different kinds of flaws an agent expression might have, as
|
||||
detected by agent_reqs. */
|
||||
enum agent_flaws
|
||||
{
|
||||
agent_flaw_none = 0, /* code is good */
|
||||
|
||||
/* There is an invalid instruction in the stream. */
|
||||
agent_flaw_bad_instruction,
|
||||
|
||||
/* There is an incomplete instruction at the end of the expression. */
|
||||
agent_flaw_incomplete_instruction,
|
||||
|
||||
/* agent_reqs was unable to prove that every jump target is to a
|
||||
valid offset. Valid offsets are within the bounds of the
|
||||
expression, and to a valid instruction boundary. */
|
||||
agent_flaw_bad_jump,
|
||||
|
||||
/* agent_reqs was unable to prove to its satisfaction that, for each
|
||||
jump target location, the stack will have the same height whether
|
||||
that location is reached via a jump or by straight execution. */
|
||||
agent_flaw_height_mismatch,
|
||||
|
||||
/* agent_reqs was unable to prove that every instruction following
|
||||
an unconditional jump was the target of some other jump. */
|
||||
agent_flaw_hole
|
||||
};
|
||||
|
||||
/* Structure describing the requirements of a bytecode expression. */
|
||||
struct agent_reqs
|
||||
{
|
||||
|
||||
/* If the following is not equal to agent_flaw_none, the rest of the
|
||||
information in this structure is suspect. */
|
||||
enum agent_flaws flaw;
|
||||
|
||||
/* Number of elements left on stack at end; may be negative if expr
|
||||
only consumes elements. */
|
||||
int final_height;
|
||||
|
||||
/* Maximum and minimum stack height, relative to initial height. */
|
||||
int max_height, min_height;
|
||||
|
||||
/* Largest `ref' or `const' opcode used, in bits. Zero means the
|
||||
expression has no such instructions. */
|
||||
int max_data_size;
|
||||
|
||||
/* Bit vector of registers used. Register R is used iff
|
||||
|
||||
reg_mask[R / 8] & (1 << (R % 8))
|
||||
|
||||
is non-zero. Note! You may not assume that this bitmask is long
|
||||
enough to hold bits for all the registers of the machine; the
|
||||
agent expression code has no idea how many registers the machine
|
||||
has. However, the bitmask is reg_mask_len bytes long, so the
|
||||
valid register numbers run from 0 to reg_mask_len * 8 - 1.
|
||||
|
||||
We're assuming eight-bit bytes. So sue me.
|
||||
|
||||
The caller should free reg_list when done. */
|
||||
int reg_mask_len;
|
||||
unsigned char *reg_mask;
|
||||
};
|
||||
|
||||
|
||||
/* Given an agent expression AX, fill in an agent_reqs structure REQS
|
||||
describing it. */
|
||||
extern void ax_reqs (struct agent_expr *ax, struct agent_reqs *reqs);
|
||||
|
||||
#endif /* AGENTEXPR_H */
|
||||
292
gdb/bcache.c
292
gdb/bcache.c
@@ -1,292 +0,0 @@
|
||||
/* Implement a cached obstack.
|
||||
Written by Fred Fish <fnf@cygnus.com>
|
||||
Rewritten by Jim Blandy <jimb@cygnus.com>
|
||||
Copyright 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "obstack.h"
|
||||
#include "bcache.h"
|
||||
#include "gdb_string.h" /* For memcpy declaration */
|
||||
|
||||
/* The old hash function was stolen from SDBM. This is what DB 3.0 uses now,
|
||||
* and is better than the old one.
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
hash(void *addr, int length)
|
||||
{
|
||||
const unsigned char *k, *e;
|
||||
unsigned long h;
|
||||
|
||||
k = (const unsigned char *)addr;
|
||||
e = k+length;
|
||||
for (h=0; k< e;++k)
|
||||
{
|
||||
h *=16777619;
|
||||
h ^= *k;
|
||||
}
|
||||
return (h);
|
||||
}
|
||||
|
||||
/* Growing the bcache's hash table. */
|
||||
|
||||
/* If the average chain length grows beyond this, then we want to
|
||||
resize our hash table. */
|
||||
#define CHAIN_LENGTH_THRESHOLD (5)
|
||||
|
||||
static void
|
||||
expand_hash_table (struct bcache *bcache)
|
||||
{
|
||||
/* A table of good hash table sizes. Whenever we grow, we pick the
|
||||
next larger size from this table. sizes[i] is close to 1 << (i+10),
|
||||
so we roughly double the table size each time. After we fall off
|
||||
the end of this table, we just double. Don't laugh --- there have
|
||||
been executables sighted with a gigabyte of debug info. */
|
||||
static unsigned long sizes[] = {
|
||||
1021, 2053, 4099, 8191, 16381, 32771,
|
||||
65537, 131071, 262144, 524287, 1048573, 2097143,
|
||||
4194301, 8388617, 16777213, 33554467, 67108859, 134217757,
|
||||
268435459, 536870923, 1073741827, 2147483659UL
|
||||
};
|
||||
unsigned int new_num_buckets;
|
||||
struct bstring **new_buckets;
|
||||
unsigned int i;
|
||||
|
||||
/* Find the next size. */
|
||||
new_num_buckets = bcache->num_buckets * 2;
|
||||
for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++)
|
||||
if (sizes[i] > bcache->num_buckets)
|
||||
{
|
||||
new_num_buckets = sizes[i];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Allocate the new table. */
|
||||
{
|
||||
size_t new_size = new_num_buckets * sizeof (new_buckets[0]);
|
||||
new_buckets = (struct bstring **) xmalloc (new_size);
|
||||
memset (new_buckets, 0, new_size);
|
||||
|
||||
bcache->structure_size -= (bcache->num_buckets
|
||||
* sizeof (bcache->bucket[0]));
|
||||
bcache->structure_size += new_size;
|
||||
}
|
||||
|
||||
/* Rehash all existing strings. */
|
||||
for (i = 0; i < bcache->num_buckets; i++)
|
||||
{
|
||||
struct bstring *s, *next;
|
||||
|
||||
for (s = bcache->bucket[i]; s; s = next)
|
||||
{
|
||||
struct bstring **new_bucket;
|
||||
next = s->next;
|
||||
|
||||
new_bucket = &new_buckets[(hash (&s->d.data, s->length)
|
||||
% new_num_buckets)];
|
||||
s->next = *new_bucket;
|
||||
*new_bucket = s;
|
||||
}
|
||||
}
|
||||
|
||||
/* Plug in the new table. */
|
||||
if (bcache->bucket)
|
||||
xfree (bcache->bucket);
|
||||
bcache->bucket = new_buckets;
|
||||
bcache->num_buckets = new_num_buckets;
|
||||
}
|
||||
|
||||
|
||||
/* Looking up things in the bcache. */
|
||||
|
||||
/* The number of bytes needed to allocate a struct bstring whose data
|
||||
is N bytes long. */
|
||||
#define BSTRING_SIZE(n) (offsetof (struct bstring, d.data) + (n))
|
||||
|
||||
/* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has
|
||||
never seen those bytes before, add a copy of them to BCACHE. In
|
||||
either case, return a pointer to BCACHE's copy of that string. */
|
||||
void *
|
||||
bcache (void *addr, int length, struct bcache *bcache)
|
||||
{
|
||||
int hash_index;
|
||||
struct bstring *s;
|
||||
|
||||
/* If our average chain length is too high, expand the hash table. */
|
||||
if (bcache->unique_count >= bcache->num_buckets * CHAIN_LENGTH_THRESHOLD)
|
||||
expand_hash_table (bcache);
|
||||
|
||||
bcache->total_count++;
|
||||
bcache->total_size += length;
|
||||
|
||||
hash_index = hash (addr, length) % bcache->num_buckets;
|
||||
|
||||
/* Search the hash bucket for a string identical to the caller's. */
|
||||
for (s = bcache->bucket[hash_index]; s; s = s->next)
|
||||
if (s->length == length
|
||||
&& ! memcmp (&s->d.data, addr, length))
|
||||
return &s->d.data;
|
||||
|
||||
/* The user's string isn't in the list. Insert it after *ps. */
|
||||
{
|
||||
struct bstring *new
|
||||
= obstack_alloc (&bcache->cache, BSTRING_SIZE (length));
|
||||
memcpy (&new->d.data, addr, length);
|
||||
new->length = length;
|
||||
new->next = bcache->bucket[hash_index];
|
||||
bcache->bucket[hash_index] = new;
|
||||
|
||||
bcache->unique_count++;
|
||||
bcache->unique_size += length;
|
||||
bcache->structure_size += BSTRING_SIZE (length);
|
||||
|
||||
return &new->d.data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Freeing bcaches. */
|
||||
|
||||
/* Free all the storage associated with BCACHE. */
|
||||
void
|
||||
free_bcache (struct bcache *bcache)
|
||||
{
|
||||
obstack_free (&bcache->cache, 0);
|
||||
if (bcache->bucket)
|
||||
xfree (bcache->bucket);
|
||||
|
||||
/* This isn't necessary, but at least the bcache is always in a
|
||||
consistent state. */
|
||||
memset (bcache, 0, sizeof (*bcache));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Printing statistics. */
|
||||
|
||||
static int
|
||||
compare_ints (const void *ap, const void *bp)
|
||||
{
|
||||
/* Because we know we're comparing two ints which are positive,
|
||||
there's no danger of overflow here. */
|
||||
return * (int *) ap - * (int *) bp;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_percentage (int portion, int total)
|
||||
{
|
||||
if (total == 0)
|
||||
printf_filtered ("(not applicable)\n");
|
||||
else
|
||||
printf_filtered ("%3d%%\n", portion * 100 / total);
|
||||
}
|
||||
|
||||
|
||||
/* Print statistics on BCACHE's memory usage and efficacity at
|
||||
eliminating duplication. NAME should describe the kind of data
|
||||
BCACHE holds. Statistics are printed using `printf_filtered' and
|
||||
its ilk. */
|
||||
void
|
||||
print_bcache_statistics (struct bcache *c, char *type)
|
||||
{
|
||||
int occupied_buckets;
|
||||
int max_chain_length;
|
||||
int median_chain_length;
|
||||
|
||||
/* Count the number of occupied buckets, and measure chain lengths. */
|
||||
{
|
||||
unsigned int b;
|
||||
int *chain_length
|
||||
= (int *) alloca (c->num_buckets * sizeof (*chain_length));
|
||||
|
||||
occupied_buckets = 0;
|
||||
|
||||
for (b = 0; b < c->num_buckets; b++)
|
||||
{
|
||||
struct bstring *s = c->bucket[b];
|
||||
|
||||
chain_length[b] = 0;
|
||||
|
||||
if (s)
|
||||
{
|
||||
occupied_buckets++;
|
||||
|
||||
while (s)
|
||||
{
|
||||
chain_length[b]++;
|
||||
s = s->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* To compute the median, we need the set of chain lengths sorted. */
|
||||
qsort (chain_length, c->num_buckets, sizeof (chain_length[0]),
|
||||
compare_ints);
|
||||
|
||||
if (c->num_buckets > 0)
|
||||
{
|
||||
max_chain_length = chain_length[c->num_buckets - 1];
|
||||
median_chain_length = chain_length[c->num_buckets / 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
max_chain_length = 0;
|
||||
median_chain_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
printf_filtered (" Cached '%s' statistics:\n", type);
|
||||
printf_filtered (" Total object count: %ld\n", c->total_count);
|
||||
printf_filtered (" Unique object count: %lu\n", c->unique_count);
|
||||
printf_filtered (" Percentage of duplicates, by count: ");
|
||||
print_percentage (c->total_count - c->unique_count, c->total_count);
|
||||
printf_filtered ("\n");
|
||||
|
||||
printf_filtered (" Total object size: %ld\n", c->total_size);
|
||||
printf_filtered (" Unique object size: %ld\n", c->unique_size);
|
||||
printf_filtered (" Percentage of duplicates, by size: ");
|
||||
print_percentage (c->total_size - c->unique_size, c->total_size);
|
||||
printf_filtered ("\n");
|
||||
|
||||
printf_filtered (" Total memory used by bcache, including overhead: %ld\n",
|
||||
c->structure_size);
|
||||
printf_filtered (" Percentage memory overhead: ");
|
||||
print_percentage (c->structure_size - c->unique_size, c->unique_size);
|
||||
printf_filtered (" Net memory savings: ");
|
||||
print_percentage (c->total_size - c->structure_size, c->total_size);
|
||||
printf_filtered ("\n");
|
||||
|
||||
printf_filtered (" Hash table size: %3d\n", c->num_buckets);
|
||||
printf_filtered (" Hash table population: ");
|
||||
print_percentage (occupied_buckets, c->num_buckets);
|
||||
printf_filtered (" Median hash chain length: %3d\n",
|
||||
median_chain_length);
|
||||
printf_filtered (" Average hash chain length: ");
|
||||
if (c->num_buckets > 0)
|
||||
printf_filtered ("%3lu\n", c->unique_count / c->num_buckets);
|
||||
else
|
||||
printf_filtered ("(not applicable)\n");
|
||||
printf_filtered (" Maximum hash chain length: %3d\n", max_chain_length);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
130
gdb/bcache.h
130
gdb/bcache.h
@@ -1,130 +0,0 @@
|
||||
/* Include file cached obstack implementation.
|
||||
Written by Fred Fish <fnf@cygnus.com>
|
||||
Rewritten by Jim Blandy <jimb@cygnus.com>
|
||||
Copyright 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef BCACHE_H
|
||||
#define BCACHE_H 1
|
||||
|
||||
/* A bcache is a data structure for factoring out duplication in
|
||||
read-only structures. You give the bcache some string of bytes S.
|
||||
If the bcache already contains a copy of S, it hands you back a
|
||||
pointer to its copy. Otherwise, it makes a fresh copy of S, and
|
||||
hands you back a pointer to that. In either case, you can throw
|
||||
away your copy of S, and use the bcache's.
|
||||
|
||||
The "strings" in question are arbitrary strings of bytes --- they
|
||||
can contain zero bytes. You pass in the length explicitly when you
|
||||
call the bcache function.
|
||||
|
||||
This means that you can put ordinary C objects in a bcache.
|
||||
However, if you do this, remember that structs can contain `holes'
|
||||
between members, added for alignment. These bytes usually contain
|
||||
garbage. If you try to bcache two objects which are identical from
|
||||
your code's point of view, but have different garbage values in the
|
||||
structure's holes, then the bcache will treat them as separate
|
||||
strings, and you won't get the nice elimination of duplicates you
|
||||
were hoping for. So, remember to memset your structures full of
|
||||
zeros before bcaching them!
|
||||
|
||||
You shouldn't modify the strings you get from a bcache, because:
|
||||
|
||||
- You don't necessarily know who you're sharing space with. If I
|
||||
stick eight bytes of text in a bcache, and then stick an
|
||||
eight-byte structure in the same bcache, there's no guarantee
|
||||
those two objects don't actually comprise the same sequence of
|
||||
bytes. If they happen to, the bcache will use a single byte
|
||||
string for both of them. Then, modifying the structure will
|
||||
change the string. In bizarre ways.
|
||||
|
||||
- Even if you know for some other reason that all that's okay,
|
||||
there's another problem. A bcache stores all its strings in a
|
||||
hash table. If you modify a string's contents, you will probably
|
||||
change its hash value. This means that the modified string is
|
||||
now in the wrong place in the hash table, and future bcache
|
||||
probes will never find it. So by mutating a string, you give up
|
||||
any chance of sharing its space with future duplicates. */
|
||||
|
||||
|
||||
/* The type used to hold a single bcache string. The user data is
|
||||
stored in d.data. Since it can be any type, it needs to have the
|
||||
same alignment as the most strict alignment of any type on the host
|
||||
machine. I don't know of any really correct way to do this in
|
||||
stock ANSI C, so just do it the same way obstack.h does.
|
||||
|
||||
It would be nicer to have this stuff hidden away in bcache.c, but
|
||||
struct objstack contains a struct bcache directly --- not a pointer
|
||||
to one --- and then the memory-mapped stuff makes this a real pain.
|
||||
We don't strictly need to expose struct bstring, but it's better to
|
||||
have it all in one place. */
|
||||
|
||||
struct bstring {
|
||||
struct bstring *next;
|
||||
size_t length;
|
||||
|
||||
union
|
||||
{
|
||||
char data[1];
|
||||
double dummy;
|
||||
}
|
||||
d;
|
||||
};
|
||||
|
||||
|
||||
/* The structure for a bcache itself.
|
||||
To initialize a bcache, just fill it with zeros. */
|
||||
struct bcache {
|
||||
/* All the bstrings are allocated here. */
|
||||
struct obstack cache;
|
||||
|
||||
/* How many hash buckets we're using. */
|
||||
unsigned int num_buckets;
|
||||
|
||||
/* Hash buckets. This table is allocated using malloc, so when we
|
||||
grow the table we can return the old table to the system. */
|
||||
struct bstring **bucket;
|
||||
|
||||
/* Statistics. */
|
||||
unsigned long unique_count; /* number of unique strings */
|
||||
long total_count; /* total number of strings cached, including dups */
|
||||
long unique_size; /* size of unique strings, in bytes */
|
||||
long total_size; /* total number of bytes cached, including dups */
|
||||
long structure_size; /* total size of bcache, including infrastructure */
|
||||
};
|
||||
|
||||
|
||||
/* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has
|
||||
never seen those bytes before, add a copy of them to BCACHE. In
|
||||
either case, return a pointer to BCACHE's copy of that string. */
|
||||
extern void *bcache (void *addr, int length, struct bcache *bcache);
|
||||
|
||||
/* Free all the storage that BCACHE refers to. The result is a valid,
|
||||
but empty, bcache. This does not free BCACHE itself, since that
|
||||
might be part of some larger object. */
|
||||
extern void free_bcache (struct bcache *bcache);
|
||||
|
||||
/* Print statistics on BCACHE's memory usage and efficacity at
|
||||
eliminating duplication. TYPE should be a string describing the
|
||||
kind of data BCACHE holds. Statistics are printed using
|
||||
`printf_filtered' and its ilk. */
|
||||
extern void print_bcache_statistics (struct bcache *bcache, char *type);
|
||||
/* The hash function */
|
||||
extern unsigned long hash(void *addr, int length);
|
||||
#endif /* BCACHE_H */
|
||||
1325
gdb/blockframe.c
1325
gdb/blockframe.c
File diff suppressed because it is too large
Load Diff
7674
gdb/breakpoint.c
7674
gdb/breakpoint.c
File diff suppressed because it is too large
Load Diff
709
gdb/breakpoint.h
709
gdb/breakpoint.h
@@ -1,709 +0,0 @@
|
||||
/* Data structures associated with breakpoints in GDB.
|
||||
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (BREAKPOINT_H)
|
||||
#define BREAKPOINT_H 1
|
||||
|
||||
#include "frame.h"
|
||||
#include "value.h"
|
||||
|
||||
#include "gdb-events.h"
|
||||
|
||||
struct value;
|
||||
|
||||
/* This is the maximum number of bytes a breakpoint instruction can take.
|
||||
Feel free to increase it. It's just used in a few places to size
|
||||
arrays that should be independent of the target architecture. */
|
||||
|
||||
#define BREAKPOINT_MAX 16
|
||||
|
||||
/* Type of breakpoint. */
|
||||
/* FIXME In the future, we should fold all other breakpoint-like things into
|
||||
here. This includes:
|
||||
|
||||
* single-step (for machines where we have to simulate single stepping)
|
||||
(probably, though perhaps it is better for it to look as much as
|
||||
possible like a single-step to wait_for_inferior). */
|
||||
|
||||
enum bptype
|
||||
{
|
||||
bp_none = 0, /* Eventpoint has been deleted. */
|
||||
bp_breakpoint, /* Normal breakpoint */
|
||||
bp_hardware_breakpoint, /* Hardware assisted breakpoint */
|
||||
bp_until, /* used by until command */
|
||||
bp_finish, /* used by finish command */
|
||||
bp_watchpoint, /* Watchpoint */
|
||||
bp_hardware_watchpoint, /* Hardware assisted watchpoint */
|
||||
bp_read_watchpoint, /* read watchpoint, (hardware assisted) */
|
||||
bp_access_watchpoint, /* access watchpoint, (hardware assisted) */
|
||||
bp_longjmp, /* secret breakpoint to find longjmp() */
|
||||
bp_longjmp_resume, /* secret breakpoint to escape longjmp() */
|
||||
|
||||
/* Used by wait_for_inferior for stepping over subroutine calls, for
|
||||
stepping over signal handlers, and for skipping prologues. */
|
||||
bp_step_resume,
|
||||
|
||||
/* Used by wait_for_inferior for stepping over signal handlers. */
|
||||
bp_through_sigtramp,
|
||||
|
||||
/* Used to detect when a watchpoint expression has gone out of
|
||||
scope. These breakpoints are usually not visible to the user.
|
||||
|
||||
This breakpoint has some interesting properties:
|
||||
|
||||
1) There's always a 1:1 mapping between watchpoints
|
||||
on local variables and watchpoint_scope breakpoints.
|
||||
|
||||
2) It automatically deletes itself and the watchpoint it's
|
||||
associated with when hit.
|
||||
|
||||
3) It can never be disabled. */
|
||||
bp_watchpoint_scope,
|
||||
|
||||
/* The breakpoint at the end of a call dummy. */
|
||||
/* FIXME: What if the function we are calling longjmp()s out of the
|
||||
call, or the user gets out with the "return" command? We currently
|
||||
have no way of cleaning up the breakpoint in these (obscure) situations.
|
||||
(Probably can solve this by noticing longjmp, "return", etc., it's
|
||||
similar to noticing when a watchpoint on a local variable goes out
|
||||
of scope (with hardware support for watchpoints)). */
|
||||
bp_call_dummy,
|
||||
|
||||
/* Some dynamic linkers (HP, maybe Solaris) can arrange for special
|
||||
code in the inferior to run when significant events occur in the
|
||||
dynamic linker (for example a library is loaded or unloaded).
|
||||
|
||||
By placing a breakpoint in this magic code GDB will get control
|
||||
when these significant events occur. GDB can then re-examine
|
||||
the dynamic linker's data structures to discover any newly loaded
|
||||
dynamic libraries. */
|
||||
bp_shlib_event,
|
||||
|
||||
/* Some multi-threaded systems can arrange for a location in the
|
||||
inferior to be executed when certain thread-related events occur
|
||||
(such as thread creation or thread death).
|
||||
|
||||
By placing a breakpoint at one of these locations, GDB will get
|
||||
control when these events occur. GDB can then update its thread
|
||||
lists etc. */
|
||||
|
||||
bp_thread_event,
|
||||
|
||||
/* On the same principal, an overlay manager can arrange to call a
|
||||
magic location in the inferior whenever there is an interesting
|
||||
change in overlay status. GDB can update its overlay tables
|
||||
and fiddle with breakpoints in overlays when this breakpoint
|
||||
is hit. */
|
||||
|
||||
bp_overlay_event,
|
||||
|
||||
/* These breakpoints are used to implement the "catch load" command
|
||||
on platforms whose dynamic linkers support such functionality. */
|
||||
bp_catch_load,
|
||||
|
||||
/* These breakpoints are used to implement the "catch unload" command
|
||||
on platforms whose dynamic linkers support such functionality. */
|
||||
bp_catch_unload,
|
||||
|
||||
/* These are not really breakpoints, but are catchpoints that
|
||||
implement the "catch fork", "catch vfork" and "catch exec" commands
|
||||
on platforms whose kernel support such functionality. (I.e.,
|
||||
kernels which can raise an event when a fork or exec occurs, as
|
||||
opposed to the debugger setting breakpoints on functions named
|
||||
"fork" or "exec".) */
|
||||
bp_catch_fork,
|
||||
bp_catch_vfork,
|
||||
bp_catch_exec,
|
||||
|
||||
/* These are catchpoints to implement "catch catch" and "catch throw"
|
||||
commands for C++ exception handling. */
|
||||
bp_catch_catch,
|
||||
bp_catch_throw
|
||||
|
||||
|
||||
};
|
||||
|
||||
/* States of enablement of breakpoint. */
|
||||
|
||||
enum enable_state
|
||||
{
|
||||
bp_disabled, /* The eventpoint is inactive, and cannot trigger. */
|
||||
bp_enabled, /* The eventpoint is active, and can trigger. */
|
||||
bp_shlib_disabled, /* The eventpoint's address is in an unloaded solib.
|
||||
The eventpoint will be automatically enabled
|
||||
and reset when that solib is loaded. */
|
||||
bp_call_disabled, /* The eventpoint has been disabled while a call
|
||||
into the inferior is "in flight", because some
|
||||
eventpoints interfere with the implementation of
|
||||
a call on some targets. The eventpoint will be
|
||||
automatically enabled and reset when the call
|
||||
"lands" (either completes, or stops at another
|
||||
eventpoint). */
|
||||
bp_permanent /* There is a breakpoint instruction hard-wired into
|
||||
the target's code. Don't try to write another
|
||||
breakpoint instruction on top of it, or restore
|
||||
its value. Step over it using the architecture's
|
||||
SKIP_INSN macro. */
|
||||
};
|
||||
|
||||
|
||||
/* Disposition of breakpoint. Ie: what to do after hitting it. */
|
||||
|
||||
enum bpdisp
|
||||
{
|
||||
disp_del, /* Delete it */
|
||||
disp_del_at_next_stop, /* Delete at next stop, whether hit or not */
|
||||
disp_disable, /* Disable it */
|
||||
disp_donttouch /* Leave it alone */
|
||||
};
|
||||
|
||||
enum target_hw_bp_type
|
||||
{
|
||||
hw_write = 0, /* Common HW watchpoint */
|
||||
hw_read = 1, /* Read HW watchpoint */
|
||||
hw_access = 2, /* Access HW watchpoint */
|
||||
hw_execute = 3 /* Execute HW breakpoint */
|
||||
};
|
||||
|
||||
/* Note that the ->silent field is not currently used by any commands
|
||||
(though the code is in there if it was to be, and set_raw_breakpoint
|
||||
does set it to 0). I implemented it because I thought it would be
|
||||
useful for a hack I had to put in; I'm going to leave it in because
|
||||
I can see how there might be times when it would indeed be useful */
|
||||
|
||||
/* This is for a breakpoint or a watchpoint. */
|
||||
|
||||
struct breakpoint
|
||||
{
|
||||
struct breakpoint *next;
|
||||
/* Type of breakpoint. */
|
||||
enum bptype type;
|
||||
/* Zero means disabled; remember the info but don't break here. */
|
||||
enum enable_state enable_state;
|
||||
/* What to do with this breakpoint after we hit it. */
|
||||
enum bpdisp disposition;
|
||||
/* Number assigned to distinguish breakpoints. */
|
||||
int number;
|
||||
|
||||
/* Address to break at.
|
||||
Note that zero is a perfectly valid code address on some
|
||||
platforms (for example, the mn10200 and mn10300 simulators).
|
||||
NULL is not a special value for this field. */
|
||||
CORE_ADDR address;
|
||||
|
||||
/* Line number of this address. */
|
||||
|
||||
int line_number;
|
||||
|
||||
/* Source file name of this address. */
|
||||
|
||||
char *source_file;
|
||||
|
||||
/* Non-zero means a silent breakpoint (don't print frame info
|
||||
if we stop here). */
|
||||
unsigned char silent;
|
||||
/* Number of stops at this breakpoint that should
|
||||
be continued automatically before really stopping. */
|
||||
int ignore_count;
|
||||
/* "Real" contents of byte where breakpoint has been inserted.
|
||||
Valid only when breakpoints are in the program. Under the complete
|
||||
control of the target insert_breakpoint and remove_breakpoint routines.
|
||||
No other code should assume anything about the value(s) here. */
|
||||
char shadow_contents[BREAKPOINT_MAX];
|
||||
/* Nonzero if this breakpoint is now inserted. */
|
||||
char inserted;
|
||||
/* Nonzero if this is not the first breakpoint in the list
|
||||
for the given address. */
|
||||
char duplicate;
|
||||
/* Chain of command lines to execute when this breakpoint is hit. */
|
||||
struct command_line *commands;
|
||||
/* Stack depth (address of frame). If nonzero, break only if fp
|
||||
equals this. */
|
||||
CORE_ADDR frame;
|
||||
/* Conditional. Break only if this expression's value is nonzero. */
|
||||
struct expression *cond;
|
||||
|
||||
/* String we used to set the breakpoint (malloc'd). */
|
||||
char *addr_string;
|
||||
/* Language we used to set the breakpoint. */
|
||||
enum language language;
|
||||
/* Input radix we used to set the breakpoint. */
|
||||
int input_radix;
|
||||
/* String form of the breakpoint condition (malloc'd), or NULL if there
|
||||
is no condition. */
|
||||
char *cond_string;
|
||||
/* String form of exp (malloc'd), or NULL if none. */
|
||||
char *exp_string;
|
||||
|
||||
/* The expression we are watching, or NULL if not a watchpoint. */
|
||||
struct expression *exp;
|
||||
/* The largest block within which it is valid, or NULL if it is
|
||||
valid anywhere (e.g. consists just of global symbols). */
|
||||
struct block *exp_valid_block;
|
||||
/* Value of the watchpoint the last time we checked it. */
|
||||
struct value *val;
|
||||
|
||||
/* Holds the value chain for a hardware watchpoint expression. */
|
||||
struct value *val_chain;
|
||||
|
||||
/* Holds the address of the related watchpoint_scope breakpoint
|
||||
when using watchpoints on local variables (might the concept
|
||||
of a related breakpoint be useful elsewhere, if not just call
|
||||
it the watchpoint_scope breakpoint or something like that. FIXME). */
|
||||
struct breakpoint *related_breakpoint;
|
||||
|
||||
/* Holds the frame address which identifies the frame this watchpoint
|
||||
should be evaluated in, or NULL if the watchpoint should be evaluated
|
||||
on the outermost frame. */
|
||||
CORE_ADDR watchpoint_frame;
|
||||
|
||||
/* Thread number for thread-specific breakpoint, or -1 if don't care */
|
||||
int thread;
|
||||
|
||||
/* Count of the number of times this breakpoint was taken, dumped
|
||||
with the info, but not used for anything else. Useful for
|
||||
seeing how many times you hit a break prior to the program
|
||||
aborting, so you can back up to just before the abort. */
|
||||
int hit_count;
|
||||
|
||||
/* Filename of a dynamically-linked library (dll), used for
|
||||
bp_catch_load and bp_catch_unload (malloc'd), or NULL if any
|
||||
library is significant. */
|
||||
char *dll_pathname;
|
||||
|
||||
/* Filename of a dll whose state change (e.g., load or unload)
|
||||
triggered this catchpoint. This field is only valid immediately
|
||||
after this catchpoint has triggered. */
|
||||
char *triggered_dll_pathname;
|
||||
|
||||
/* Process id of a child process whose forking triggered this
|
||||
catchpoint. This field is only valid immediately after this
|
||||
catchpoint has triggered. */
|
||||
int forked_inferior_pid;
|
||||
|
||||
/* Filename of a program whose exec triggered this catchpoint.
|
||||
This field is only valid immediately after this catchpoint has
|
||||
triggered. */
|
||||
char *exec_pathname;
|
||||
|
||||
asection *section;
|
||||
};
|
||||
|
||||
/* The following stuff is an abstract data type "bpstat" ("breakpoint
|
||||
status"). This provides the ability to determine whether we have
|
||||
stopped at a breakpoint, and what we should do about it. */
|
||||
|
||||
typedef struct bpstats *bpstat;
|
||||
|
||||
/* Interface: */
|
||||
/* Clear a bpstat so that it says we are not at any breakpoint.
|
||||
Also free any storage that is part of a bpstat. */
|
||||
extern void bpstat_clear (bpstat *);
|
||||
|
||||
/* Return a copy of a bpstat. Like "bs1 = bs2" but all storage that
|
||||
is part of the bpstat is copied as well. */
|
||||
extern bpstat bpstat_copy (bpstat);
|
||||
|
||||
extern bpstat bpstat_stop_status (CORE_ADDR *, int);
|
||||
|
||||
/* This bpstat_what stuff tells wait_for_inferior what to do with a
|
||||
breakpoint (a challenging task). */
|
||||
|
||||
enum bpstat_what_main_action
|
||||
{
|
||||
/* Perform various other tests; that is, this bpstat does not
|
||||
say to perform any action (e.g. failed watchpoint and nothing
|
||||
else). */
|
||||
BPSTAT_WHAT_KEEP_CHECKING,
|
||||
|
||||
/* Rather than distinguish between noisy and silent stops here, it
|
||||
might be cleaner to have bpstat_print make that decision (also
|
||||
taking into account stop_print_frame and source_only). But the
|
||||
implications are a bit scary (interaction with auto-displays, etc.),
|
||||
so I won't try it. */
|
||||
|
||||
/* Stop silently. */
|
||||
BPSTAT_WHAT_STOP_SILENT,
|
||||
|
||||
/* Stop and print. */
|
||||
BPSTAT_WHAT_STOP_NOISY,
|
||||
|
||||
/* Remove breakpoints, single step once, then put them back in and
|
||||
go back to what we were doing. It's possible that this should be
|
||||
removed from the main_action and put into a separate field, to more
|
||||
cleanly handle BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE. */
|
||||
BPSTAT_WHAT_SINGLE,
|
||||
|
||||
/* Set longjmp_resume breakpoint, remove all other breakpoints,
|
||||
and continue. The "remove all other breakpoints" part is required
|
||||
if we are also stepping over another breakpoint as well as doing
|
||||
the longjmp handling. */
|
||||
BPSTAT_WHAT_SET_LONGJMP_RESUME,
|
||||
|
||||
/* Clear longjmp_resume breakpoint, then handle as
|
||||
BPSTAT_WHAT_KEEP_CHECKING. */
|
||||
BPSTAT_WHAT_CLEAR_LONGJMP_RESUME,
|
||||
|
||||
/* Clear longjmp_resume breakpoint, then handle as BPSTAT_WHAT_SINGLE. */
|
||||
BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE,
|
||||
|
||||
/* Clear step resume breakpoint, and keep checking. */
|
||||
BPSTAT_WHAT_STEP_RESUME,
|
||||
|
||||
/* Clear through_sigtramp breakpoint, muck with trap_expected, and keep
|
||||
checking. */
|
||||
BPSTAT_WHAT_THROUGH_SIGTRAMP,
|
||||
|
||||
/* Check the dynamic linker's data structures for new libraries, then
|
||||
keep checking. */
|
||||
BPSTAT_WHAT_CHECK_SHLIBS,
|
||||
|
||||
/* Check the dynamic linker's data structures for new libraries, then
|
||||
resume out of the dynamic linker's callback, stop and print. */
|
||||
BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK,
|
||||
|
||||
/* This is just used to keep track of how many enums there are. */
|
||||
BPSTAT_WHAT_LAST
|
||||
};
|
||||
|
||||
struct bpstat_what
|
||||
{
|
||||
enum bpstat_what_main_action main_action;
|
||||
|
||||
/* Did we hit a call dummy breakpoint? This only goes with a main_action
|
||||
of BPSTAT_WHAT_STOP_SILENT or BPSTAT_WHAT_STOP_NOISY (the concept of
|
||||
continuing from a call dummy without popping the frame is not a
|
||||
useful one). */
|
||||
int call_dummy;
|
||||
};
|
||||
|
||||
/* The possible return values for print_bpstat, print_it_normal,
|
||||
print_it_done, print_it_noop. */
|
||||
enum print_stop_action
|
||||
{
|
||||
PRINT_UNKNOWN = -1,
|
||||
PRINT_SRC_AND_LOC,
|
||||
PRINT_SRC_ONLY,
|
||||
PRINT_NOTHING
|
||||
};
|
||||
|
||||
/* Tell what to do about this bpstat. */
|
||||
struct bpstat_what bpstat_what (bpstat);
|
||||
|
||||
/* Find the bpstat associated with a breakpoint. NULL otherwise. */
|
||||
bpstat bpstat_find_breakpoint (bpstat, struct breakpoint *);
|
||||
|
||||
/* Find a step_resume breakpoint associated with this bpstat.
|
||||
(If there are multiple step_resume bp's on the list, this function
|
||||
will arbitrarily pick one.)
|
||||
|
||||
It is an error to use this function if BPSTAT doesn't contain a
|
||||
step_resume breakpoint.
|
||||
|
||||
See wait_for_inferior's use of this function.
|
||||
*/
|
||||
extern struct breakpoint *bpstat_find_step_resume_breakpoint (bpstat);
|
||||
|
||||
/* Nonzero if a signal that we got in wait() was due to circumstances
|
||||
explained by the BS. */
|
||||
/* Currently that is true if we have hit a breakpoint, or if there is
|
||||
a watchpoint enabled. */
|
||||
#define bpstat_explains_signal(bs) ((bs) != NULL)
|
||||
|
||||
/* Nonzero if we should step constantly (e.g. watchpoints on machines
|
||||
without hardware support). This isn't related to a specific bpstat,
|
||||
just to things like whether watchpoints are set. */
|
||||
extern int bpstat_should_step (void);
|
||||
|
||||
/* Nonzero if there are enabled hardware watchpoints. */
|
||||
extern int bpstat_have_active_hw_watchpoints (void);
|
||||
|
||||
/* Print a message indicating what happened. Returns nonzero to
|
||||
say that only the source line should be printed after this (zero
|
||||
return means print the frame as well as the source line). */
|
||||
extern enum print_stop_action bpstat_print (bpstat);
|
||||
|
||||
/* Return the breakpoint number of the first breakpoint we are stopped
|
||||
at. *BSP upon return is a bpstat which points to the remaining
|
||||
breakpoints stopped at (but which is not guaranteed to be good for
|
||||
anything but further calls to bpstat_num).
|
||||
Return 0 if passed a bpstat which does not indicate any breakpoints. */
|
||||
extern int bpstat_num (bpstat *);
|
||||
|
||||
/* Perform actions associated with having stopped at *BSP. Actually, we just
|
||||
use this for breakpoint commands. Perhaps other actions will go here
|
||||
later, but this is executed at a late time (from the command loop). */
|
||||
extern void bpstat_do_actions (bpstat *);
|
||||
|
||||
/* Modify BS so that the actions will not be performed. */
|
||||
extern void bpstat_clear_actions (bpstat);
|
||||
|
||||
/* Given a bpstat that records zero or more triggered eventpoints, this
|
||||
function returns another bpstat which contains only the catchpoints
|
||||
on that first list, if any.
|
||||
*/
|
||||
extern void bpstat_get_triggered_catchpoints (bpstat, bpstat *);
|
||||
|
||||
/* Implementation: */
|
||||
|
||||
/* Values used to tell the printing routine how to behave for this bpstat. */
|
||||
enum bp_print_how
|
||||
{
|
||||
/* This is used when we want to do a normal printing of the reason
|
||||
for stopping. The output will depend on the type of eventpoint
|
||||
we are dealing with. This is the default value, most commonly
|
||||
used. */
|
||||
print_it_normal,
|
||||
/* This is used when nothing should be printed for this bpstat entry. */
|
||||
print_it_noop,
|
||||
/* This is used when everything which needs to be printed has
|
||||
already been printed. But we still want to print the frame. */
|
||||
print_it_done
|
||||
};
|
||||
|
||||
struct bpstats
|
||||
{
|
||||
/* Linked list because there can be two breakpoints at the same
|
||||
place, and a bpstat reflects the fact that both have been hit. */
|
||||
bpstat next;
|
||||
/* Breakpoint that we are at. */
|
||||
struct breakpoint *breakpoint_at;
|
||||
/* Commands left to be done. */
|
||||
struct command_line *commands;
|
||||
/* Old value associated with a watchpoint. */
|
||||
struct value *old_val;
|
||||
|
||||
/* Nonzero if this breakpoint tells us to print the frame. */
|
||||
char print;
|
||||
|
||||
/* Nonzero if this breakpoint tells us to stop. */
|
||||
char stop;
|
||||
|
||||
/* Tell bpstat_print and print_bp_stop_message how to print stuff
|
||||
associated with this element of the bpstat chain. */
|
||||
enum bp_print_how print_it;
|
||||
};
|
||||
|
||||
enum inf_context
|
||||
{
|
||||
inf_starting,
|
||||
inf_running,
|
||||
inf_exited
|
||||
};
|
||||
|
||||
/* The possible return values for breakpoint_here_p.
|
||||
We guarantee that zero always means "no breakpoint here". */
|
||||
enum breakpoint_here
|
||||
{
|
||||
no_breakpoint_here = 0,
|
||||
ordinary_breakpoint_here,
|
||||
permanent_breakpoint_here
|
||||
};
|
||||
|
||||
|
||||
/* Prototypes for breakpoint-related functions. */
|
||||
|
||||
/* Forward declarations for prototypes */
|
||||
struct frame_info;
|
||||
|
||||
extern enum breakpoint_here breakpoint_here_p (CORE_ADDR);
|
||||
|
||||
extern int breakpoint_inserted_here_p (CORE_ADDR);
|
||||
|
||||
extern int frame_in_dummy (struct frame_info *);
|
||||
|
||||
extern int breakpoint_thread_match (CORE_ADDR, ptid_t);
|
||||
|
||||
extern void until_break_command (char *, int);
|
||||
|
||||
extern void breakpoint_re_set (void);
|
||||
|
||||
extern void breakpoint_re_set_thread (struct breakpoint *);
|
||||
|
||||
extern int ep_is_exception_catchpoint (struct breakpoint *);
|
||||
|
||||
extern struct breakpoint *set_momentary_breakpoint
|
||||
(struct symtab_and_line, struct frame_info *, enum bptype);
|
||||
|
||||
extern void set_ignore_count (int, int, int);
|
||||
|
||||
extern void set_default_breakpoint (int, CORE_ADDR, struct symtab *, int);
|
||||
|
||||
extern void mark_breakpoints_out (void);
|
||||
|
||||
extern void breakpoint_init_inferior (enum inf_context);
|
||||
|
||||
extern struct cleanup *make_cleanup_delete_breakpoint (struct breakpoint *);
|
||||
|
||||
extern struct cleanup *make_exec_cleanup_delete_breakpoint (struct breakpoint *);
|
||||
|
||||
extern void delete_breakpoint (struct breakpoint *);
|
||||
|
||||
extern void breakpoint_auto_delete (bpstat);
|
||||
|
||||
extern void breakpoint_clear_ignore_counts (void);
|
||||
|
||||
extern void break_command (char *, int);
|
||||
|
||||
extern void hbreak_command_wrapper (char *, int);
|
||||
extern void thbreak_command_wrapper (char *, int);
|
||||
extern void rbreak_command_wrapper (char *, int);
|
||||
extern void watch_command_wrapper (char *, int);
|
||||
extern void awatch_command_wrapper (char *, int);
|
||||
extern void rwatch_command_wrapper (char *, int);
|
||||
extern void tbreak_command (char *, int);
|
||||
|
||||
extern int insert_breakpoints (void);
|
||||
|
||||
extern int remove_breakpoints (void);
|
||||
|
||||
/* This function can be used to physically insert eventpoints from the
|
||||
specified traced inferior process, without modifying the breakpoint
|
||||
package's state. This can be useful for those targets which support
|
||||
following the processes of a fork() or vfork() system call, when both
|
||||
of the resulting two processes are to be followed. */
|
||||
extern int reattach_breakpoints (int);
|
||||
|
||||
/* This function can be used to update the breakpoint package's state
|
||||
after an exec() system call has been executed.
|
||||
|
||||
This function causes the following:
|
||||
|
||||
- All eventpoints are marked "not inserted".
|
||||
- All eventpoints with a symbolic address are reset such that
|
||||
the symbolic address must be reevaluated before the eventpoints
|
||||
can be reinserted.
|
||||
- The solib breakpoints are explicitly removed from the breakpoint
|
||||
list.
|
||||
- A step-resume breakpoint, if any, is explicitly removed from the
|
||||
breakpoint list.
|
||||
- All eventpoints without a symbolic address are removed from the
|
||||
breakpoint list. */
|
||||
extern void update_breakpoints_after_exec (void);
|
||||
|
||||
/* This function can be used to physically remove hardware breakpoints
|
||||
and watchpoints from the specified traced inferior process, without
|
||||
modifying the breakpoint package's state. This can be useful for
|
||||
those targets which support following the processes of a fork() or
|
||||
vfork() system call, when one of the resulting two processes is to
|
||||
be detached and allowed to run free.
|
||||
|
||||
It is an error to use this function on the process whose id is
|
||||
inferior_ptid. */
|
||||
extern int detach_breakpoints (int);
|
||||
|
||||
extern void enable_longjmp_breakpoint (void);
|
||||
extern void disable_longjmp_breakpoint (void);
|
||||
extern void enable_overlay_breakpoints (void);
|
||||
extern void disable_overlay_breakpoints (void);
|
||||
|
||||
extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_info *);
|
||||
/* These functions respectively disable or reenable all currently
|
||||
enabled watchpoints. When disabled, the watchpoints are marked
|
||||
call_disabled. When reenabled, they are marked enabled.
|
||||
|
||||
The intended client of these functions is infcmd.c\run_stack_dummy.
|
||||
|
||||
The inferior must be stopped, and all breakpoints removed, when
|
||||
these functions are used.
|
||||
|
||||
The need for these functions is that on some targets (e.g., HP-UX),
|
||||
gdb is unable to unwind through the dummy frame that is pushed as
|
||||
part of the implementation of a call command. Watchpoints can
|
||||
cause the inferior to stop in places where this frame is visible,
|
||||
and that can cause execution control to become very confused.
|
||||
|
||||
Note that if a user sets breakpoints in an interactively called
|
||||
function, the call_disabled watchpoints will have been reenabled
|
||||
when the first such breakpoint is reached. However, on targets
|
||||
that are unable to unwind through the call dummy frame, watches
|
||||
of stack-based storage may then be deleted, because gdb will
|
||||
believe that their watched storage is out of scope. (Sigh.) */
|
||||
extern void disable_watchpoints_before_interactive_call_start (void);
|
||||
|
||||
extern void enable_watchpoints_after_interactive_call_stop (void);
|
||||
|
||||
|
||||
extern void clear_breakpoint_hit_counts (void);
|
||||
|
||||
extern int get_number (char **);
|
||||
|
||||
extern int get_number_or_range (char **);
|
||||
|
||||
/* The following are for displays, which aren't really breakpoints, but
|
||||
here is as good a place as any for them. */
|
||||
|
||||
extern void disable_current_display (void);
|
||||
|
||||
extern void do_displays (void);
|
||||
|
||||
extern void disable_display (int);
|
||||
|
||||
extern void clear_displays (void);
|
||||
|
||||
extern void disable_breakpoint (struct breakpoint *);
|
||||
|
||||
extern void enable_breakpoint (struct breakpoint *);
|
||||
|
||||
extern void make_breakpoint_permanent (struct breakpoint *);
|
||||
|
||||
extern struct breakpoint *create_solib_event_breakpoint (CORE_ADDR);
|
||||
|
||||
extern struct breakpoint *create_thread_event_breakpoint (CORE_ADDR);
|
||||
|
||||
extern void remove_solib_event_breakpoints (void);
|
||||
|
||||
extern void remove_thread_event_breakpoints (void);
|
||||
|
||||
extern void disable_breakpoints_in_shlibs (int silent);
|
||||
|
||||
extern void re_enable_breakpoints_in_shlibs (void);
|
||||
|
||||
extern void create_solib_load_event_breakpoint (char *, int, char *, char *);
|
||||
|
||||
extern void create_solib_unload_event_breakpoint (char *, int,
|
||||
char *, char *);
|
||||
|
||||
extern void create_fork_event_catchpoint (int, char *);
|
||||
|
||||
extern void create_vfork_event_catchpoint (int, char *);
|
||||
|
||||
extern void create_exec_event_catchpoint (int, char *);
|
||||
|
||||
/* This function returns TRUE if ep is a catchpoint. */
|
||||
extern int ep_is_catchpoint (struct breakpoint *);
|
||||
|
||||
/* This function returns TRUE if ep is a catchpoint of a
|
||||
shared library (aka dynamically-linked library) event,
|
||||
such as a library load or unload. */
|
||||
extern int ep_is_shlib_catchpoint (struct breakpoint *);
|
||||
|
||||
extern struct breakpoint *set_breakpoint_sal (struct symtab_and_line);
|
||||
|
||||
/* Enable breakpoints and delete when hit. Called with ARG == NULL
|
||||
deletes all breakpoints. */
|
||||
extern void delete_command (char *arg, int from_tty);
|
||||
|
||||
/* Pull all H/W watchpoints from the target. Return non-zero if the
|
||||
remove fails. */
|
||||
extern int remove_hw_watchpoints (void);
|
||||
|
||||
#endif /* !defined (BREAKPOINT_H) */
|
||||
1125
gdb/buildsym.c
1125
gdb/buildsym.c
File diff suppressed because it is too large
Load Diff
301
gdb/buildsym.h
301
gdb/buildsym.h
@@ -1,301 +0,0 @@
|
||||
/* Build symbol tables in GDB's internal format.
|
||||
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1996,
|
||||
1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (BUILDSYM_H)
|
||||
#define BUILDSYM_H 1
|
||||
|
||||
/* This module provides definitions used for creating and adding to
|
||||
the symbol table. These routines are called from various symbol-
|
||||
file-reading routines.
|
||||
|
||||
They originated in dbxread.c of gdb-4.2, and were split out to
|
||||
make xcoffread.c more maintainable by sharing code.
|
||||
|
||||
Variables declared in this file can be defined by #define-ing the
|
||||
name EXTERN to null. It is used to declare variables that are
|
||||
normally extern, but which get defined in a single module using
|
||||
this technique. */
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#define HASHSIZE 127 /* Size of things hashed via
|
||||
hashname() */
|
||||
|
||||
/* Name of source file whose symbol data we are now processing. This
|
||||
comes from a symbol of type N_SO. */
|
||||
|
||||
EXTERN char *last_source_file;
|
||||
|
||||
/* Core address of start of text of current source file. This too
|
||||
comes from the N_SO symbol. */
|
||||
|
||||
EXTERN CORE_ADDR last_source_start_addr;
|
||||
|
||||
/* The list of sub-source-files within the current individual
|
||||
compilation. Each file gets its own symtab with its own linetable
|
||||
and associated info, but they all share one blockvector. */
|
||||
|
||||
struct subfile
|
||||
{
|
||||
struct subfile *next;
|
||||
char *name;
|
||||
char *dirname;
|
||||
struct linetable *line_vector;
|
||||
int line_vector_length;
|
||||
enum language language;
|
||||
char *debugformat;
|
||||
};
|
||||
|
||||
EXTERN struct subfile *subfiles;
|
||||
|
||||
EXTERN struct subfile *current_subfile;
|
||||
|
||||
/* Global variable which, when set, indicates that we are processing a
|
||||
.o file compiled with gcc */
|
||||
|
||||
EXTERN unsigned char processing_gcc_compilation;
|
||||
|
||||
/* When set, we are processing a .o file compiled by sun acc. This is
|
||||
misnamed; it refers to all stabs-in-elf implementations which use
|
||||
N_UNDF the way Sun does, including Solaris gcc. Hopefully all
|
||||
stabs-in-elf implementations ever invented will choose to be
|
||||
compatible. */
|
||||
|
||||
EXTERN unsigned char processing_acc_compilation;
|
||||
|
||||
/* elz: added this flag to know when a block is compiled with HP
|
||||
compilers (cc, aCC). This is necessary because of the macro
|
||||
COERCE_FLOAT_TO_DOUBLE defined in tm_hppa.h, which causes a
|
||||
coercion of float to double to always occur in parameter passing
|
||||
for a function called by gdb (see the function value_arg_coerce in
|
||||
valops.c). This is necessary only if the target was compiled with
|
||||
gcc, not with HP compilers or with g++ */
|
||||
|
||||
EXTERN unsigned char processing_hp_compilation;
|
||||
|
||||
/* Count symbols as they are processed, for error messages. */
|
||||
|
||||
EXTERN unsigned int symnum;
|
||||
|
||||
/* Record the symbols defined for each context in a list. We don't
|
||||
create a struct block for the context until we know how long to
|
||||
make it. */
|
||||
|
||||
#define PENDINGSIZE 100
|
||||
|
||||
struct pending
|
||||
{
|
||||
struct pending *next;
|
||||
int nsyms;
|
||||
struct symbol *symbol[PENDINGSIZE];
|
||||
};
|
||||
|
||||
/* Here are the three lists that symbols are put on. */
|
||||
|
||||
/* static at top level, and types */
|
||||
|
||||
EXTERN struct pending *file_symbols;
|
||||
|
||||
/* global functions and variables */
|
||||
|
||||
EXTERN struct pending *global_symbols;
|
||||
|
||||
/* everything local to lexical context */
|
||||
|
||||
EXTERN struct pending *local_symbols;
|
||||
|
||||
/* func params local to lexical context */
|
||||
|
||||
EXTERN struct pending *param_symbols;
|
||||
|
||||
/* Stack representing unclosed lexical contexts (that will become
|
||||
blocks, eventually). */
|
||||
|
||||
struct context_stack
|
||||
{
|
||||
/* Outer locals at the time we entered */
|
||||
|
||||
struct pending *locals;
|
||||
|
||||
/* Pending func params at the time we entered */
|
||||
|
||||
struct pending *params;
|
||||
|
||||
/* Pointer into blocklist as of entry */
|
||||
|
||||
struct pending_block *old_blocks;
|
||||
|
||||
/* Name of function, if any, defining context */
|
||||
|
||||
struct symbol *name;
|
||||
|
||||
/* PC where this context starts */
|
||||
|
||||
CORE_ADDR start_addr;
|
||||
|
||||
/* Temp slot for exception handling. */
|
||||
|
||||
CORE_ADDR end_addr;
|
||||
|
||||
/* For error-checking matching push/pop */
|
||||
|
||||
int depth;
|
||||
|
||||
};
|
||||
|
||||
EXTERN struct context_stack *context_stack;
|
||||
|
||||
/* Index of first unused entry in context stack. */
|
||||
|
||||
EXTERN int context_stack_depth;
|
||||
|
||||
/* Currently allocated size of context stack. */
|
||||
|
||||
EXTERN int context_stack_size;
|
||||
|
||||
/* Macro "function" for popping contexts from the stack. Pushing is
|
||||
done by a real function, push_context. This returns a pointer to a
|
||||
struct context_stack. */
|
||||
|
||||
#define pop_context() (&context_stack[--context_stack_depth]);
|
||||
|
||||
/* Nonzero if within a function (so symbols should be local, if
|
||||
nothing says specifically). */
|
||||
|
||||
EXTERN int within_function;
|
||||
|
||||
/* List of blocks already made (lexical contexts already closed).
|
||||
This is used at the end to make the blockvector. */
|
||||
|
||||
struct pending_block
|
||||
{
|
||||
struct pending_block *next;
|
||||
struct block *block;
|
||||
};
|
||||
|
||||
/* Pointer to the head of a linked list of symbol blocks which have
|
||||
already been finalized (lexical contexts already closed) and which
|
||||
are just waiting to be built into a blockvector when finalizing the
|
||||
associated symtab. */
|
||||
|
||||
EXTERN struct pending_block *pending_blocks;
|
||||
|
||||
|
||||
struct subfile_stack
|
||||
{
|
||||
struct subfile_stack *next;
|
||||
char *name;
|
||||
};
|
||||
|
||||
EXTERN struct subfile_stack *subfile_stack;
|
||||
|
||||
#define next_symbol_text(objfile) (*next_symbol_text_func)(objfile)
|
||||
|
||||
/* Function to invoke get the next symbol. Return the symbol name. */
|
||||
|
||||
EXTERN char *(*next_symbol_text_func) (struct objfile *);
|
||||
|
||||
/* Vector of types defined so far, indexed by their type numbers.
|
||||
Used for both stabs and coff. (In newer sun systems, dbx uses a
|
||||
pair of numbers in parens, as in "(SUBFILENUM,NUMWITHINSUBFILE)".
|
||||
Then these numbers must be translated through the type_translations
|
||||
hash table to get the index into the type vector.) */
|
||||
|
||||
EXTERN struct type **type_vector;
|
||||
|
||||
/* Number of elements allocated for type_vector currently. */
|
||||
|
||||
EXTERN int type_vector_length;
|
||||
|
||||
/* Initial size of type vector. Is realloc'd larger if needed, and
|
||||
realloc'd down to the size actually used, when completed. */
|
||||
|
||||
#define INITIAL_TYPE_VECTOR_LENGTH 160
|
||||
|
||||
extern void add_free_pendings (struct pending *list);
|
||||
|
||||
extern void add_symbol_to_list (struct symbol *symbol,
|
||||
struct pending **listhead);
|
||||
|
||||
extern struct symbol *find_symbol_in_list (struct pending *list,
|
||||
char *name, int length);
|
||||
|
||||
extern void finish_block (struct symbol *symbol,
|
||||
struct pending **listhead,
|
||||
struct pending_block *old_blocks,
|
||||
CORE_ADDR start, CORE_ADDR end,
|
||||
struct objfile *objfile);
|
||||
|
||||
extern void really_free_pendings (PTR dummy);
|
||||
|
||||
extern void start_subfile (char *name, char *dirname);
|
||||
|
||||
extern void patch_subfile_names (struct subfile *subfile, char *name);
|
||||
|
||||
extern void push_subfile (void);
|
||||
|
||||
extern char *pop_subfile (void);
|
||||
|
||||
extern struct symtab *end_symtab (CORE_ADDR end_addr,
|
||||
struct objfile *objfile, int section);
|
||||
|
||||
/* Defined in stabsread.c. */
|
||||
|
||||
extern void scan_file_globals (struct objfile *objfile);
|
||||
|
||||
extern void buildsym_new_init (void);
|
||||
|
||||
extern void buildsym_init (void);
|
||||
|
||||
extern struct context_stack *push_context (int desc, CORE_ADDR valu);
|
||||
|
||||
extern void record_line (struct subfile *subfile, int line, CORE_ADDR pc);
|
||||
|
||||
extern void start_symtab (char *name, char *dirname, CORE_ADDR start_addr);
|
||||
|
||||
extern int hashname (char *name);
|
||||
|
||||
extern void free_pending_blocks (void);
|
||||
|
||||
/* FIXME: Note that this is used only in buildsym.c and dstread.c,
|
||||
which should be fixed to not need direct access to
|
||||
make_blockvector. */
|
||||
|
||||
extern struct blockvector *make_blockvector (struct objfile *objfile);
|
||||
|
||||
/* FIXME: Note that this is used only in buildsym.c and dstread.c,
|
||||
which should be fixed to not need direct access to
|
||||
record_pending_block. */
|
||||
|
||||
extern void record_pending_block (struct objfile *objfile,
|
||||
struct block *block,
|
||||
struct pending_block *opblock);
|
||||
|
||||
extern void record_debugformat (char *format);
|
||||
|
||||
extern void merge_symbol_lists (struct pending **srclist,
|
||||
struct pending **targetlist);
|
||||
|
||||
#undef EXTERN
|
||||
|
||||
#endif /* defined (BUILDSYM_H) */
|
||||
1742
gdb/c-exp.y
1742
gdb/c-exp.y
File diff suppressed because it is too large
Load Diff
526
gdb/c-lang.c
526
gdb/c-lang.c
@@ -1,526 +0,0 @@
|
||||
/* C language support routines for GDB, the GNU debugger.
|
||||
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "parser-defs.h"
|
||||
#include "language.h"
|
||||
#include "c-lang.h"
|
||||
#include "valprint.h"
|
||||
|
||||
extern void _initialize_c_language (void);
|
||||
static void c_emit_char (int c, struct ui_file * stream, int quoter);
|
||||
|
||||
/* Print the character C on STREAM as part of the contents of a literal
|
||||
string whose delimiter is QUOTER. Note that that format for printing
|
||||
characters and strings is language specific. */
|
||||
|
||||
static void
|
||||
c_emit_char (register int c, struct ui_file *stream, int quoter)
|
||||
{
|
||||
c &= 0xFF; /* Avoid sign bit follies */
|
||||
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
if (c == '\\' || c == quoter)
|
||||
{
|
||||
fputs_filtered ("\\", stream);
|
||||
}
|
||||
fprintf_filtered (stream, "%c", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
fputs_filtered ("\\n", stream);
|
||||
break;
|
||||
case '\b':
|
||||
fputs_filtered ("\\b", stream);
|
||||
break;
|
||||
case '\t':
|
||||
fputs_filtered ("\\t", stream);
|
||||
break;
|
||||
case '\f':
|
||||
fputs_filtered ("\\f", stream);
|
||||
break;
|
||||
case '\r':
|
||||
fputs_filtered ("\\r", stream);
|
||||
break;
|
||||
case '\013':
|
||||
fputs_filtered ("\\v", stream);
|
||||
break;
|
||||
case '\033':
|
||||
fputs_filtered ("\\e", stream);
|
||||
break;
|
||||
case '\007':
|
||||
fputs_filtered ("\\a", stream);
|
||||
break;
|
||||
case '\0':
|
||||
fputs_filtered ("\\0", stream);
|
||||
break;
|
||||
default:
|
||||
fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
c_printchar (int c, struct ui_file *stream)
|
||||
{
|
||||
fputc_filtered ('\'', stream);
|
||||
LA_EMIT_CHAR (c, stream, '\'');
|
||||
fputc_filtered ('\'', stream);
|
||||
}
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
LENGTH is -1 if the string is nul terminated. Each character is WIDTH bytes
|
||||
long. Printing stops early if the number hits print_max; repeat counts are
|
||||
printed as appropriate. Print ellipses at the end if we had to stop before
|
||||
printing LENGTH characters, or if FORCE_ELLIPSES. */
|
||||
|
||||
void
|
||||
c_printstr (struct ui_file *stream, char *string, unsigned int length,
|
||||
int width, int force_ellipses)
|
||||
{
|
||||
register unsigned int i;
|
||||
unsigned int things_printed = 0;
|
||||
int in_quotes = 0;
|
||||
int need_comma = 0;
|
||||
extern int inspect_it;
|
||||
|
||||
/* If the string was not truncated due to `set print elements', and
|
||||
the last byte of it is a null, we don't print that, in traditional C
|
||||
style. */
|
||||
if (!force_ellipses
|
||||
&& length > 0
|
||||
&& (extract_unsigned_integer (string + (length - 1) * width, width)
|
||||
== '\0'))
|
||||
length--;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
fputs_filtered ("\"\"", stream);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < length && things_printed < print_max; ++i)
|
||||
{
|
||||
/* Position of the character we are examining
|
||||
to see whether it is repeated. */
|
||||
unsigned int rep1;
|
||||
/* Number of repetitions we have detected so far. */
|
||||
unsigned int reps;
|
||||
unsigned long current_char;
|
||||
|
||||
QUIT;
|
||||
|
||||
if (need_comma)
|
||||
{
|
||||
fputs_filtered (", ", stream);
|
||||
need_comma = 0;
|
||||
}
|
||||
|
||||
current_char = extract_unsigned_integer (string + i * width, width);
|
||||
|
||||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while (rep1 < length
|
||||
&& extract_unsigned_integer (string + rep1 * width, width)
|
||||
== current_char)
|
||||
{
|
||||
++rep1;
|
||||
++reps;
|
||||
}
|
||||
|
||||
if (reps > repeat_count_threshold)
|
||||
{
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\", ", stream);
|
||||
else
|
||||
fputs_filtered ("\", ", stream);
|
||||
in_quotes = 0;
|
||||
}
|
||||
LA_PRINT_CHAR (current_char, stream);
|
||||
fprintf_filtered (stream, " <repeats %u times>", reps);
|
||||
i = rep1 - 1;
|
||||
things_printed += repeat_count_threshold;
|
||||
need_comma = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
in_quotes = 1;
|
||||
}
|
||||
LA_EMIT_CHAR (current_char, stream, '"');
|
||||
++things_printed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the quotes if necessary. */
|
||||
if (in_quotes)
|
||||
{
|
||||
if (inspect_it)
|
||||
fputs_filtered ("\\\"", stream);
|
||||
else
|
||||
fputs_filtered ("\"", stream);
|
||||
}
|
||||
|
||||
if (force_ellipses || i < length)
|
||||
fputs_filtered ("...", stream);
|
||||
}
|
||||
|
||||
/* Create a fundamental C type using default reasonable for the current
|
||||
target machine.
|
||||
|
||||
Some object/debugging file formats (DWARF version 1, COFF, etc) do not
|
||||
define fundamental types such as "int" or "double". Others (stabs or
|
||||
DWARF version 2, etc) do define fundamental types. For the formats which
|
||||
don't provide fundamental types, gdb can create such types using this
|
||||
function.
|
||||
|
||||
FIXME: Some compilers distinguish explicitly signed integral types
|
||||
(signed short, signed int, signed long) from "regular" integral types
|
||||
(short, int, long) in the debugging information. There is some dis-
|
||||
agreement as to how useful this feature is. In particular, gcc does
|
||||
not support this. Also, only some debugging formats allow the
|
||||
distinction to be passed on to a debugger. For now, we always just
|
||||
use "short", "int", or "long" as the type name, for both the implicit
|
||||
and explicitly signed types. This also makes life easier for the
|
||||
gdb test suite since we don't have to account for the differences
|
||||
in output depending upon what the compiler and debugging format
|
||||
support. We will probably have to re-examine the issue when gdb
|
||||
starts taking it's fundamental type information directly from the
|
||||
debugging information supplied by the compiler. fnf@cygnus.com */
|
||||
|
||||
struct type *
|
||||
c_create_fundamental_type (struct objfile *objfile, int typeid)
|
||||
{
|
||||
register struct type *type = NULL;
|
||||
|
||||
switch (typeid)
|
||||
{
|
||||
default:
|
||||
/* FIXME: For now, if we are asked to produce a type not in this
|
||||
language, create the equivalent of a C integer type with the
|
||||
name "<?type?>". When all the dust settles from the type
|
||||
reconstruction work, this should probably become an error. */
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
0, "<?type?>", objfile);
|
||||
warning ("internal error: no C/C++ fundamental type %d", typeid);
|
||||
break;
|
||||
case FT_VOID:
|
||||
type = init_type (TYPE_CODE_VOID,
|
||||
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
0, "void", objfile);
|
||||
break;
|
||||
case FT_BOOLEAN:
|
||||
type = init_type (TYPE_CODE_BOOL,
|
||||
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
0, "bool", objfile);
|
||||
break;
|
||||
case FT_CHAR:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_NOSIGN, "char", objfile);
|
||||
break;
|
||||
case FT_SIGNED_CHAR:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
0, "signed char", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_CHAR:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED, "unsigned char", objfile);
|
||||
break;
|
||||
case FT_SHORT:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_SHORT_BIT / TARGET_CHAR_BIT,
|
||||
0, "short", objfile);
|
||||
break;
|
||||
case FT_SIGNED_SHORT:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_SHORT_BIT / TARGET_CHAR_BIT,
|
||||
0, "short", objfile); /* FIXME-fnf */
|
||||
break;
|
||||
case FT_UNSIGNED_SHORT:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_SHORT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
|
||||
break;
|
||||
case FT_INTEGER:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
0, "int", objfile);
|
||||
break;
|
||||
case FT_SIGNED_INTEGER:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
0, "int", objfile); /* FIXME -fnf */
|
||||
break;
|
||||
case FT_UNSIGNED_INTEGER:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_INT_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
|
||||
break;
|
||||
case FT_LONG:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0, "long", objfile);
|
||||
break;
|
||||
case FT_SIGNED_LONG:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0, "long", objfile); /* FIXME -fnf */
|
||||
break;
|
||||
case FT_UNSIGNED_LONG:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
|
||||
break;
|
||||
case FT_LONG_LONG:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0, "long long", objfile);
|
||||
break;
|
||||
case FT_SIGNED_LONG_LONG:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0, "signed long long", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_LONG_LONG:
|
||||
type = init_type (TYPE_CODE_INT,
|
||||
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
|
||||
break;
|
||||
case FT_FLOAT:
|
||||
type = init_type (TYPE_CODE_FLT,
|
||||
TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
|
||||
0, "float", objfile);
|
||||
break;
|
||||
case FT_DBL_PREC_FLOAT:
|
||||
type = init_type (TYPE_CODE_FLT,
|
||||
TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
|
||||
0, "double", objfile);
|
||||
break;
|
||||
case FT_EXT_PREC_FLOAT:
|
||||
type = init_type (TYPE_CODE_FLT,
|
||||
TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
|
||||
0, "long double", objfile);
|
||||
break;
|
||||
case FT_TEMPLATE_ARG:
|
||||
type = init_type (TYPE_CODE_TEMPLATE_ARG,
|
||||
0,
|
||||
0, "<template arg>", objfile);
|
||||
break;
|
||||
}
|
||||
return (type);
|
||||
}
|
||||
|
||||
|
||||
/* Table mapping opcodes into strings for printing operators
|
||||
and precedences of the operators. */
|
||||
|
||||
const struct op_print c_op_print_tab[] =
|
||||
{
|
||||
{",", BINOP_COMMA, PREC_COMMA, 0},
|
||||
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
|
||||
{"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
|
||||
{"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
|
||||
{"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
|
||||
{"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
|
||||
{"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
|
||||
{"==", BINOP_EQUAL, PREC_EQUAL, 0},
|
||||
{"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
|
||||
{"<=", BINOP_LEQ, PREC_ORDER, 0},
|
||||
{">=", BINOP_GEQ, PREC_ORDER, 0},
|
||||
{">", BINOP_GTR, PREC_ORDER, 0},
|
||||
{"<", BINOP_LESS, PREC_ORDER, 0},
|
||||
{">>", BINOP_RSH, PREC_SHIFT, 0},
|
||||
{"<<", BINOP_LSH, PREC_SHIFT, 0},
|
||||
{"+", BINOP_ADD, PREC_ADD, 0},
|
||||
{"-", BINOP_SUB, PREC_ADD, 0},
|
||||
{"*", BINOP_MUL, PREC_MUL, 0},
|
||||
{"/", BINOP_DIV, PREC_MUL, 0},
|
||||
{"%", BINOP_REM, PREC_MUL, 0},
|
||||
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
|
||||
{"-", UNOP_NEG, PREC_PREFIX, 0},
|
||||
{"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
|
||||
{"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
|
||||
{"*", UNOP_IND, PREC_PREFIX, 0},
|
||||
{"&", UNOP_ADDR, PREC_PREFIX, 0},
|
||||
{"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
|
||||
{"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
|
||||
{"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
struct type **CONST_PTR (c_builtin_types[]) =
|
||||
{
|
||||
&builtin_type_int,
|
||||
&builtin_type_long,
|
||||
&builtin_type_short,
|
||||
&builtin_type_char,
|
||||
&builtin_type_float,
|
||||
&builtin_type_double,
|
||||
&builtin_type_void,
|
||||
&builtin_type_long_long,
|
||||
&builtin_type_signed_char,
|
||||
&builtin_type_unsigned_char,
|
||||
&builtin_type_unsigned_short,
|
||||
&builtin_type_unsigned_int,
|
||||
&builtin_type_unsigned_long,
|
||||
&builtin_type_unsigned_long_long,
|
||||
&builtin_type_long_double,
|
||||
&builtin_type_complex,
|
||||
&builtin_type_double_complex,
|
||||
0
|
||||
};
|
||||
|
||||
const struct language_defn c_language_defn =
|
||||
{
|
||||
"c", /* Language name */
|
||||
language_c,
|
||||
c_builtin_types,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
case_sensitive_on,
|
||||
c_parse,
|
||||
c_error,
|
||||
evaluate_subexp_standard,
|
||||
c_printchar, /* Print a character constant */
|
||||
c_printstr, /* Function to print string constant */
|
||||
c_emit_char, /* Print a single char */
|
||||
c_create_fundamental_type, /* Create fundamental type in this language */
|
||||
c_print_type, /* Print a type using appropriate syntax */
|
||||
c_val_print, /* Print a value using appropriate syntax */
|
||||
c_value_print, /* Print a top-level value */
|
||||
{"", "", "", ""}, /* Binary format info */
|
||||
{"0%lo", "0", "o", ""}, /* Octal format info */
|
||||
{"%ld", "", "d", ""}, /* Decimal format info */
|
||||
{"0x%lx", "0x", "x", ""}, /* Hex format info */
|
||||
c_op_print_tab, /* expression operators for printing */
|
||||
1, /* c-style arrays */
|
||||
0, /* String lower bound */
|
||||
&builtin_type_char, /* Type of string elements */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
struct type **const (cplus_builtin_types[]) =
|
||||
{
|
||||
&builtin_type_int,
|
||||
&builtin_type_long,
|
||||
&builtin_type_short,
|
||||
&builtin_type_char,
|
||||
&builtin_type_float,
|
||||
&builtin_type_double,
|
||||
&builtin_type_void,
|
||||
&builtin_type_long_long,
|
||||
&builtin_type_signed_char,
|
||||
&builtin_type_unsigned_char,
|
||||
&builtin_type_unsigned_short,
|
||||
&builtin_type_unsigned_int,
|
||||
&builtin_type_unsigned_long,
|
||||
&builtin_type_unsigned_long_long,
|
||||
&builtin_type_long_double,
|
||||
&builtin_type_complex,
|
||||
&builtin_type_double_complex,
|
||||
&builtin_type_bool,
|
||||
0
|
||||
};
|
||||
|
||||
const struct language_defn cplus_language_defn =
|
||||
{
|
||||
"c++", /* Language name */
|
||||
language_cplus,
|
||||
cplus_builtin_types,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
case_sensitive_on,
|
||||
c_parse,
|
||||
c_error,
|
||||
evaluate_subexp_standard,
|
||||
c_printchar, /* Print a character constant */
|
||||
c_printstr, /* Function to print string constant */
|
||||
c_emit_char, /* Print a single char */
|
||||
c_create_fundamental_type, /* Create fundamental type in this language */
|
||||
c_print_type, /* Print a type using appropriate syntax */
|
||||
c_val_print, /* Print a value using appropriate syntax */
|
||||
c_value_print, /* Print a top-level value */
|
||||
{"", "", "", ""}, /* Binary format info */
|
||||
{"0%lo", "0", "o", ""}, /* Octal format info */
|
||||
{"%ld", "", "d", ""}, /* Decimal format info */
|
||||
{"0x%lx", "0x", "x", ""}, /* Hex format info */
|
||||
c_op_print_tab, /* expression operators for printing */
|
||||
1, /* c-style arrays */
|
||||
0, /* String lower bound */
|
||||
&builtin_type_char, /* Type of string elements */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
const struct language_defn asm_language_defn =
|
||||
{
|
||||
"asm", /* Language name */
|
||||
language_asm,
|
||||
c_builtin_types,
|
||||
range_check_off,
|
||||
type_check_off,
|
||||
case_sensitive_on,
|
||||
c_parse,
|
||||
c_error,
|
||||
evaluate_subexp_standard,
|
||||
c_printchar, /* Print a character constant */
|
||||
c_printstr, /* Function to print string constant */
|
||||
c_emit_char, /* Print a single char */
|
||||
c_create_fundamental_type, /* Create fundamental type in this language */
|
||||
c_print_type, /* Print a type using appropriate syntax */
|
||||
c_val_print, /* Print a value using appropriate syntax */
|
||||
c_value_print, /* Print a top-level value */
|
||||
{"", "", "", ""}, /* Binary format info */
|
||||
{"0%lo", "0", "o", ""}, /* Octal format info */
|
||||
{"%ld", "", "d", ""}, /* Decimal format info */
|
||||
{"0x%lx", "0x", "x", ""}, /* Hex format info */
|
||||
c_op_print_tab, /* expression operators for printing */
|
||||
1, /* c-style arrays */
|
||||
0, /* String lower bound */
|
||||
&builtin_type_char, /* Type of string elements */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
void
|
||||
_initialize_c_language (void)
|
||||
{
|
||||
add_language (&c_language_defn);
|
||||
add_language (&cplus_language_defn);
|
||||
add_language (&asm_language_defn);
|
||||
}
|
||||
84
gdb/c-lang.h
84
gdb/c-lang.h
@@ -1,84 +0,0 @@
|
||||
/* C language support definitions for GDB, the GNU debugger.
|
||||
Copyright 1992, 1994, 1995, 1996, 1997, 1998, 2000
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#if !defined (C_LANG_H)
|
||||
#define C_LANG_H 1
|
||||
|
||||
#include "value.h"
|
||||
|
||||
|
||||
extern int c_parse (void); /* Defined in c-exp.y */
|
||||
|
||||
extern void c_error (char *); /* Defined in c-exp.y */
|
||||
|
||||
/* Defined in c-typeprint.c */
|
||||
extern void c_print_type (struct type *, char *, struct ui_file *, int,
|
||||
int);
|
||||
|
||||
extern int c_val_print (struct type *, char *, int, CORE_ADDR,
|
||||
struct ui_file *, int, int, int,
|
||||
enum val_prettyprint);
|
||||
|
||||
extern int c_value_print (struct value *, struct ui_file *, int,
|
||||
enum val_prettyprint);
|
||||
|
||||
/* These are in c-lang.c: */
|
||||
|
||||
extern void c_printchar (int, struct ui_file *);
|
||||
|
||||
extern void c_printstr (struct ui_file * stream, char *string,
|
||||
unsigned int length, int width,
|
||||
int force_ellipses);
|
||||
|
||||
extern struct type *c_create_fundamental_type (struct objfile *, int);
|
||||
|
||||
extern struct type **CONST_PTR (c_builtin_types[]);
|
||||
|
||||
/* These are in c-typeprint.c: */
|
||||
|
||||
extern void c_type_print_base (struct type *, struct ui_file *, int, int);
|
||||
|
||||
extern void c_type_print_varspec_prefix (struct type *, struct ui_file *,
|
||||
int, int);
|
||||
|
||||
/* These are in cp-valprint.c */
|
||||
|
||||
extern int vtblprint; /* Controls printing of vtbl's */
|
||||
|
||||
extern int static_field_print;
|
||||
|
||||
extern void cp_print_class_member (char *, struct type *, struct ui_file *,
|
||||
char *);
|
||||
|
||||
extern void cp_print_class_method (char *, struct type *, struct ui_file *);
|
||||
|
||||
extern void cp_print_value_fields (struct type *, struct type *, char *,
|
||||
int, CORE_ADDR, struct ui_file *, int,
|
||||
int, enum val_prettyprint,
|
||||
struct type **, int);
|
||||
|
||||
extern int cp_is_vtbl_ptr_type (struct type *);
|
||||
|
||||
extern int cp_is_vtbl_member (struct type *);
|
||||
|
||||
|
||||
#endif /* !defined (C_LANG_H) */
|
||||
1190
gdb/c-typeprint.c
1190
gdb/c-typeprint.c
File diff suppressed because it is too large
Load Diff
598
gdb/c-valprint.c
598
gdb/c-valprint.c
@@ -1,598 +0,0 @@
|
||||
/* Support for printing C values for GDB, the GNU debugger.
|
||||
Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "value.h"
|
||||
#include "valprint.h"
|
||||
#include "language.h"
|
||||
#include "c-lang.h"
|
||||
#include "cp-abi.h"
|
||||
|
||||
|
||||
/* Print function pointer with inferior address ADDRESS onto stdio
|
||||
stream STREAM. */
|
||||
|
||||
static void
|
||||
print_function_pointer_address (CORE_ADDR address, struct ui_file *stream)
|
||||
{
|
||||
CORE_ADDR func_addr = CONVERT_FROM_FUNC_PTR_ADDR (address);
|
||||
|
||||
/* If the function pointer is represented by a description, print the
|
||||
address of the description. */
|
||||
if (addressprint && func_addr != address)
|
||||
{
|
||||
fputs_filtered ("@", stream);
|
||||
print_address_numeric (address, 1, stream);
|
||||
fputs_filtered (": ", stream);
|
||||
}
|
||||
print_address_demangle (func_addr, stream, demangle);
|
||||
}
|
||||
|
||||
|
||||
/* Print data of type TYPE located at VALADDR (within GDB), which came from
|
||||
the inferior at address ADDRESS, onto stdio stream STREAM according to
|
||||
FORMAT (a letter or 0 for natural format). The data at VALADDR is in
|
||||
target byte order.
|
||||
|
||||
If the data are a string pointer, returns the number of string characters
|
||||
printed.
|
||||
|
||||
If DEREF_REF is nonzero, then dereference references, otherwise just print
|
||||
them like pointers.
|
||||
|
||||
The PRETTY parameter controls prettyprinting. */
|
||||
|
||||
int
|
||||
c_val_print (struct type *type, char *valaddr, int embedded_offset,
|
||||
CORE_ADDR address, struct ui_file *stream, int format,
|
||||
int deref_ref, int recurse, enum val_prettyprint pretty)
|
||||
{
|
||||
register unsigned int i = 0; /* Number of characters printed */
|
||||
unsigned len;
|
||||
struct type *elttype;
|
||||
unsigned eltlen;
|
||||
LONGEST val;
|
||||
CORE_ADDR addr;
|
||||
|
||||
CHECK_TYPEDEF (type);
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
|
||||
{
|
||||
eltlen = TYPE_LENGTH (elttype);
|
||||
len = TYPE_LENGTH (type) / eltlen;
|
||||
if (prettyprint_arrays)
|
||||
{
|
||||
print_spaces_filtered (2 + 2 * recurse, stream);
|
||||
}
|
||||
/* For an array of chars, print with string syntax. */
|
||||
if (eltlen == 1 &&
|
||||
((TYPE_CODE (elttype) == TYPE_CODE_INT)
|
||||
|| ((current_language->la_language == language_m2)
|
||||
&& (TYPE_CODE (elttype) == TYPE_CODE_CHAR)))
|
||||
&& (format == 0 || format == 's'))
|
||||
{
|
||||
/* If requested, look for the first null char and only print
|
||||
elements up to it. */
|
||||
if (stop_print_at_null)
|
||||
{
|
||||
unsigned int temp_len;
|
||||
|
||||
/* Look for a NULL char. */
|
||||
for (temp_len = 0;
|
||||
(valaddr + embedded_offset)[temp_len]
|
||||
&& temp_len < len && temp_len < print_max;
|
||||
temp_len++);
|
||||
len = temp_len;
|
||||
}
|
||||
|
||||
LA_PRINT_STRING (stream, valaddr + embedded_offset, len, eltlen, 0);
|
||||
i = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "{");
|
||||
/* If this is a virtual function table, print the 0th
|
||||
entry specially, and the rest of the members normally. */
|
||||
if (cp_is_vtbl_ptr_type (elttype))
|
||||
{
|
||||
i = 1;
|
||||
fprintf_filtered (stream, "%d vtable entries", len - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
val_print_array_elements (type, valaddr + embedded_offset, address, stream,
|
||||
format, deref_ref, recurse, pretty, i);
|
||||
fprintf_filtered (stream, "}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Array of unspecified length: treat like pointer to first elt. */
|
||||
addr = address;
|
||||
goto print_unpacked_pointer;
|
||||
|
||||
case TYPE_CODE_PTR:
|
||||
if (format && format != 's')
|
||||
{
|
||||
print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
|
||||
break;
|
||||
}
|
||||
if (vtblprint && cp_is_vtbl_ptr_type (type))
|
||||
{
|
||||
/* Print the unmangled name if desired. */
|
||||
/* Print vtable entry - we only get here if we ARE using
|
||||
-fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */
|
||||
CORE_ADDR addr
|
||||
= extract_typed_address (valaddr + embedded_offset, type);
|
||||
print_function_pointer_address (addr, stream);
|
||||
break;
|
||||
}
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
if (TYPE_CODE (elttype) == TYPE_CODE_METHOD)
|
||||
{
|
||||
cp_print_class_method (valaddr + embedded_offset, type, stream);
|
||||
}
|
||||
else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
|
||||
{
|
||||
cp_print_class_member (valaddr + embedded_offset,
|
||||
TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
|
||||
stream, "&");
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = unpack_pointer (type, valaddr + embedded_offset);
|
||||
print_unpacked_pointer:
|
||||
|
||||
if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
|
||||
{
|
||||
/* Try to print what function it points to. */
|
||||
print_function_pointer_address (addr, stream);
|
||||
/* Return value is irrelevant except for string pointers. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (addressprint && format != 's')
|
||||
{
|
||||
print_address_numeric (addr, 1, stream);
|
||||
}
|
||||
|
||||
/* For a pointer to char or unsigned char, also print the string
|
||||
pointed to, unless pointer is null. */
|
||||
/* FIXME: need to handle wchar_t here... */
|
||||
|
||||
if (TYPE_LENGTH (elttype) == 1
|
||||
&& TYPE_CODE (elttype) == TYPE_CODE_INT
|
||||
&& (format == 0 || format == 's')
|
||||
&& addr != 0)
|
||||
{
|
||||
i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
|
||||
}
|
||||
else if (cp_is_vtbl_member (type))
|
||||
{
|
||||
/* print vtbl's nicely */
|
||||
CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset);
|
||||
|
||||
struct minimal_symbol *msymbol =
|
||||
lookup_minimal_symbol_by_pc (vt_address);
|
||||
if ((msymbol != NULL) &&
|
||||
(vt_address == SYMBOL_VALUE_ADDRESS (msymbol)))
|
||||
{
|
||||
fputs_filtered (" <", stream);
|
||||
fputs_filtered (SYMBOL_SOURCE_NAME (msymbol), stream);
|
||||
fputs_filtered (">", stream);
|
||||
}
|
||||
if (vt_address && vtblprint)
|
||||
{
|
||||
struct value *vt_val;
|
||||
struct symbol *wsym = (struct symbol *) NULL;
|
||||
struct type *wtype;
|
||||
struct symtab *s;
|
||||
struct block *block = (struct block *) NULL;
|
||||
int is_this_fld;
|
||||
|
||||
if (msymbol != NULL)
|
||||
wsym = lookup_symbol (SYMBOL_NAME (msymbol), block,
|
||||
VAR_NAMESPACE, &is_this_fld, &s);
|
||||
|
||||
if (wsym)
|
||||
{
|
||||
wtype = SYMBOL_TYPE (wsym);
|
||||
}
|
||||
else
|
||||
{
|
||||
wtype = TYPE_TARGET_TYPE (type);
|
||||
}
|
||||
vt_val = value_at (wtype, vt_address, NULL);
|
||||
val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val), 0,
|
||||
VALUE_ADDRESS (vt_val), stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
if (pretty)
|
||||
{
|
||||
fprintf_filtered (stream, "\n");
|
||||
print_spaces_filtered (2 + 2 * recurse, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return number of characters printed, including the terminating
|
||||
'\0' if we reached the end. val_print_string takes care including
|
||||
the terminating '\0' if necessary. */
|
||||
return i;
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_MEMBER:
|
||||
error ("not implemented: member type in c_val_print");
|
||||
break;
|
||||
|
||||
case TYPE_CODE_REF:
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
|
||||
{
|
||||
cp_print_class_member (valaddr + embedded_offset,
|
||||
TYPE_DOMAIN_TYPE (elttype),
|
||||
stream, "");
|
||||
break;
|
||||
}
|
||||
if (addressprint)
|
||||
{
|
||||
CORE_ADDR addr
|
||||
= extract_typed_address (valaddr + embedded_offset, type);
|
||||
fprintf_filtered (stream, "@");
|
||||
print_address_numeric (addr, 1, stream);
|
||||
if (deref_ref)
|
||||
fputs_filtered (": ", stream);
|
||||
}
|
||||
/* De-reference the reference. */
|
||||
if (deref_ref)
|
||||
{
|
||||
if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
|
||||
{
|
||||
struct value *deref_val =
|
||||
value_at
|
||||
(TYPE_TARGET_TYPE (type),
|
||||
unpack_pointer (lookup_pointer_type (builtin_type_void),
|
||||
valaddr + embedded_offset),
|
||||
NULL);
|
||||
val_print (VALUE_TYPE (deref_val),
|
||||
VALUE_CONTENTS (deref_val),
|
||||
0,
|
||||
VALUE_ADDRESS (deref_val),
|
||||
stream,
|
||||
format,
|
||||
deref_ref,
|
||||
recurse,
|
||||
pretty);
|
||||
}
|
||||
else
|
||||
fputs_filtered ("???", stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_UNION:
|
||||
if (recurse && !unionprint)
|
||||
{
|
||||
fprintf_filtered (stream, "{...}");
|
||||
break;
|
||||
}
|
||||
/* Fall through. */
|
||||
case TYPE_CODE_STRUCT:
|
||||
/*FIXME: Abstract this away */
|
||||
if (vtblprint && cp_is_vtbl_ptr_type (type))
|
||||
{
|
||||
/* Print the unmangled name if desired. */
|
||||
/* Print vtable entry - we only get here if NOT using
|
||||
-fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */
|
||||
int offset = (embedded_offset +
|
||||
TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8);
|
||||
struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET);
|
||||
CORE_ADDR addr
|
||||
= extract_typed_address (valaddr + offset, field_type);
|
||||
|
||||
print_function_pointer_address (addr, stream);
|
||||
}
|
||||
else
|
||||
cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format,
|
||||
recurse, pretty, NULL, 0);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_ENUM:
|
||||
if (format)
|
||||
{
|
||||
print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
|
||||
break;
|
||||
}
|
||||
len = TYPE_NFIELDS (type);
|
||||
val = unpack_long (type, valaddr + embedded_offset);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
QUIT;
|
||||
if (val == TYPE_FIELD_BITPOS (type, i))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < len)
|
||||
{
|
||||
fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_longest (stream, 'd', 0, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_FUNC:
|
||||
if (format)
|
||||
{
|
||||
print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
|
||||
break;
|
||||
}
|
||||
/* FIXME, we should consider, at least for ANSI C language, eliminating
|
||||
the distinction made between FUNCs and POINTERs to FUNCs. */
|
||||
fprintf_filtered (stream, "{");
|
||||
type_print (type, "", stream, -1);
|
||||
fprintf_filtered (stream, "} ");
|
||||
/* Try to print what function it points to, and its address. */
|
||||
print_address_demangle (address, stream, demangle);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_BOOL:
|
||||
format = format ? format : output_format;
|
||||
if (format)
|
||||
print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
|
||||
else
|
||||
{
|
||||
val = unpack_long (type, valaddr + embedded_offset);
|
||||
if (val == 0)
|
||||
fputs_filtered ("false", stream);
|
||||
else if (val == 1)
|
||||
fputs_filtered ("true", stream);
|
||||
else
|
||||
print_longest (stream, 'd', 0, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_RANGE:
|
||||
/* FIXME: create_range_type does not set the unsigned bit in a
|
||||
range type (I think it probably should copy it from the target
|
||||
type), so we won't print values which are too large to
|
||||
fit in a signed integer correctly. */
|
||||
/* FIXME: Doesn't handle ranges of enums correctly. (Can't just
|
||||
print with the target type, though, because the size of our type
|
||||
and the target type might differ). */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case TYPE_CODE_INT:
|
||||
format = format ? format : output_format;
|
||||
if (format)
|
||||
{
|
||||
print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
val_print_type_code_int (type, valaddr + embedded_offset, stream);
|
||||
/* C and C++ has no single byte int type, char is used instead.
|
||||
Since we don't know whether the value is really intended to
|
||||
be used as an integer or a character, print the character
|
||||
equivalent as well. */
|
||||
if (TYPE_LENGTH (type) == 1)
|
||||
{
|
||||
fputs_filtered (" ", stream);
|
||||
LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset),
|
||||
stream);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_CHAR:
|
||||
format = format ? format : output_format;
|
||||
if (format)
|
||||
{
|
||||
print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = unpack_long (type, valaddr + embedded_offset);
|
||||
if (TYPE_UNSIGNED (type))
|
||||
fprintf_filtered (stream, "%u", (unsigned int) val);
|
||||
else
|
||||
fprintf_filtered (stream, "%d", (int) val);
|
||||
fputs_filtered (" ", stream);
|
||||
LA_PRINT_CHAR ((unsigned char) val, stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_FLT:
|
||||
if (format)
|
||||
{
|
||||
print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_floating (valaddr + embedded_offset, type, stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_METHOD:
|
||||
{
|
||||
struct value *v = value_at (type, address, NULL);
|
||||
cp_print_class_method (VALUE_CONTENTS (value_addr (v)),
|
||||
lookup_pointer_type (type), stream);
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_CODE_VOID:
|
||||
fprintf_filtered (stream, "void");
|
||||
break;
|
||||
|
||||
case TYPE_CODE_ERROR:
|
||||
fprintf_filtered (stream, "<error type>");
|
||||
break;
|
||||
|
||||
case TYPE_CODE_UNDEF:
|
||||
/* This happens (without TYPE_FLAG_STUB set) on systems which don't use
|
||||
dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
|
||||
and no complete type for struct foo in that file. */
|
||||
fprintf_filtered (stream, "<incomplete type>");
|
||||
break;
|
||||
|
||||
case TYPE_CODE_COMPLEX:
|
||||
if (format)
|
||||
print_scalar_formatted (valaddr + embedded_offset,
|
||||
TYPE_TARGET_TYPE (type),
|
||||
format, 0, stream);
|
||||
else
|
||||
print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type),
|
||||
stream);
|
||||
fprintf_filtered (stream, " + ");
|
||||
if (format)
|
||||
print_scalar_formatted (valaddr + embedded_offset
|
||||
+ TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
|
||||
TYPE_TARGET_TYPE (type),
|
||||
format, 0, stream);
|
||||
else
|
||||
print_floating (valaddr + embedded_offset
|
||||
+ TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
|
||||
TYPE_TARGET_TYPE (type),
|
||||
stream);
|
||||
fprintf_filtered (stream, " * I");
|
||||
break;
|
||||
|
||||
default:
|
||||
error ("Invalid C/C++ type code %d in symbol table.", TYPE_CODE (type));
|
||||
}
|
||||
gdb_flush (stream);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
c_value_print (struct value *val, struct ui_file *stream, int format,
|
||||
enum val_prettyprint pretty)
|
||||
{
|
||||
struct type *type = VALUE_TYPE (val);
|
||||
struct type *real_type;
|
||||
int full, top, using_enc;
|
||||
|
||||
/* If it is a pointer, indicate what it points to.
|
||||
|
||||
Print type also if it is a reference.
|
||||
|
||||
C++: if it is a member pointer, we will take care
|
||||
of that when we print it. */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_PTR ||
|
||||
TYPE_CODE (type) == TYPE_CODE_REF)
|
||||
{
|
||||
/* Hack: remove (char *) for char strings. Their
|
||||
type is indicated by the quoted string anyway. */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_PTR &&
|
||||
TYPE_NAME (type) == NULL &&
|
||||
TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL &&
|
||||
STREQ (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char"))
|
||||
{
|
||||
/* Print nothing */
|
||||
}
|
||||
else if (objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
|
||||
{
|
||||
|
||||
if (TYPE_CODE(type) == TYPE_CODE_REF)
|
||||
{
|
||||
/* Copy value, change to pointer, so we don't get an
|
||||
* error about a non-pointer type in value_rtti_target_type
|
||||
*/
|
||||
struct value *temparg;
|
||||
temparg=value_copy(val);
|
||||
VALUE_TYPE (temparg) = lookup_pointer_type(TYPE_TARGET_TYPE(type));
|
||||
val=temparg;
|
||||
}
|
||||
/* Pointer to class, check real type of object */
|
||||
fprintf_filtered (stream, "(");
|
||||
real_type = value_rtti_target_type (val, &full, &top, &using_enc);
|
||||
if (real_type)
|
||||
{
|
||||
/* RTTI entry found */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_PTR)
|
||||
{
|
||||
/* create a pointer type pointing to the real type */
|
||||
type = lookup_pointer_type (real_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a reference type referencing the real type */
|
||||
type = lookup_reference_type (real_type);
|
||||
}
|
||||
/* JYG: Need to adjust pointer value. */
|
||||
val->aligner.contents[0] -= top;
|
||||
|
||||
/* Note: When we look up RTTI entries, we don't get any
|
||||
information on const or volatile attributes */
|
||||
}
|
||||
type_print (type, "", stream, -1);
|
||||
fprintf_filtered (stream, ") ");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* normal case */
|
||||
fprintf_filtered (stream, "(");
|
||||
type_print (type, "", stream, -1);
|
||||
fprintf_filtered (stream, ") ");
|
||||
}
|
||||
}
|
||||
if (objectprint && (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_CLASS))
|
||||
{
|
||||
/* Attempt to determine real type of object */
|
||||
real_type = value_rtti_type (val, &full, &top, &using_enc);
|
||||
if (real_type)
|
||||
{
|
||||
/* We have RTTI information, so use it */
|
||||
val = value_full_object (val, real_type, full, top, using_enc);
|
||||
fprintf_filtered (stream, "(%s%s) ",
|
||||
TYPE_NAME (real_type),
|
||||
full ? "" : " [incomplete object]");
|
||||
/* Print out object: enclosing type is same as real_type if full */
|
||||
return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0,
|
||||
VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
|
||||
/* Note: When we look up RTTI entries, we don't get any information on
|
||||
const or volatile attributes */
|
||||
}
|
||||
else if (type != VALUE_ENCLOSING_TYPE (val))
|
||||
{
|
||||
/* No RTTI information, so let's do our best */
|
||||
fprintf_filtered (stream, "(%s ?) ",
|
||||
TYPE_NAME (VALUE_ENCLOSING_TYPE (val)));
|
||||
return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0,
|
||||
VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
|
||||
}
|
||||
/* Otherwise, we end up at the return outside this "if" */
|
||||
}
|
||||
|
||||
return val_print (type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val),
|
||||
VALUE_ADDRESS (val),
|
||||
stream, format, 1, 0, pretty);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/* ***DEPRECATED*** The gdblib files must not be calling/using things in any
|
||||
of the possible command languages. If necessary, a hook (that may be
|
||||
present or not) must be used and set to the appropriate routine by any
|
||||
command language that cares about it. If you are having to include this
|
||||
file you are possibly doing things the old way. This file will disapear.
|
||||
2000-12-01 fnasser@redhat.com */
|
||||
|
||||
/* Prototypes for GDB commands that are called internally by other functions.
|
||||
Copyright 1992, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef CALL_CMDS_H
|
||||
#define CALL_CMDS_H
|
||||
|
||||
extern void initialize_all_files (void);
|
||||
|
||||
extern void core_file_command (char *, int);
|
||||
|
||||
extern void break_command (char *, int);
|
||||
|
||||
#endif
|
||||
2233
gdb/ch-exp.c
2233
gdb/ch-exp.c
File diff suppressed because it is too large
Load Diff
663
gdb/ch-lang.c
663
gdb/ch-lang.c
@@ -1,663 +0,0 @@
|
||||
/* Chill language support routines for GDB, the GNU debugger.
|
||||
Copyright 1992, 1993, 1994, 1995, 1996, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "value.h"
|
||||
#include "expression.h"
|
||||
#include "parser-defs.h"
|
||||
#include "language.h"
|
||||
#include "ch-lang.h"
|
||||
#include "valprint.h"
|
||||
|
||||
extern void _initialize_chill_language (void);
|
||||
|
||||
static struct value *evaluate_subexp_chill (struct type *, struct expression *,
|
||||
int *, enum noside);
|
||||
|
||||
static struct value *value_chill_max_min (enum exp_opcode, struct value *);
|
||||
|
||||
static struct value *value_chill_card (struct value *);
|
||||
|
||||
static struct value *value_chill_length (struct value *);
|
||||
|
||||
static struct type *chill_create_fundamental_type (struct objfile *, int);
|
||||
|
||||
static void chill_printstr (struct ui_file * stream, char *string,
|
||||
unsigned int length, int width,
|
||||
int force_ellipses);
|
||||
|
||||
static void chill_printchar (int, struct ui_file *);
|
||||
|
||||
/* For now, Chill uses a simple mangling algorithm whereby you simply
|
||||
discard everything after the occurance of two successive CPLUS_MARKER
|
||||
characters to derive the demangled form. */
|
||||
|
||||
char *
|
||||
chill_demangle (const char *mangled)
|
||||
{
|
||||
const char *joiner = NULL;
|
||||
char *demangled;
|
||||
const char *cp = mangled;
|
||||
|
||||
while (*cp)
|
||||
{
|
||||
if (is_cplus_marker (*cp))
|
||||
{
|
||||
joiner = cp;
|
||||
break;
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
if (joiner != NULL && *(joiner + 1) == *joiner)
|
||||
{
|
||||
demangled = savestring (mangled, joiner - mangled);
|
||||
}
|
||||
else
|
||||
{
|
||||
demangled = NULL;
|
||||
}
|
||||
return (demangled);
|
||||
}
|
||||
|
||||
static void
|
||||
chill_printchar (register int c, struct ui_file *stream)
|
||||
{
|
||||
c &= 0xFF; /* Avoid sign bit follies */
|
||||
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
if (c == '\'' || c == '^')
|
||||
fprintf_filtered (stream, "'%c%c'", c, c);
|
||||
else
|
||||
fprintf_filtered (stream, "'%c'", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "'^(%u)'", (unsigned int) c);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
Printing stops early if the number hits print_max; repeat counts
|
||||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
|
||||
Note that gdb maintains the length of strings without counting the
|
||||
terminating null byte, while chill strings are typically written with
|
||||
an explicit null byte. So we always assume an implied null byte
|
||||
until gdb is able to maintain non-null terminated strings as well
|
||||
as null terminated strings (FIXME).
|
||||
*/
|
||||
|
||||
static void
|
||||
chill_printstr (struct ui_file *stream, char *string, unsigned int length,
|
||||
int width, int force_ellipses)
|
||||
{
|
||||
register unsigned int i;
|
||||
unsigned int things_printed = 0;
|
||||
int in_literal_form = 0;
|
||||
int in_control_form = 0;
|
||||
int need_slashslash = 0;
|
||||
unsigned int c;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
fputs_filtered ("\"\"", stream);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < length && things_printed < print_max; ++i)
|
||||
{
|
||||
/* Position of the character we are examining
|
||||
to see whether it is repeated. */
|
||||
unsigned int rep1;
|
||||
/* Number of repetitions we have detected so far. */
|
||||
unsigned int reps;
|
||||
|
||||
QUIT;
|
||||
|
||||
if (need_slashslash)
|
||||
{
|
||||
fputs_filtered ("//", stream);
|
||||
need_slashslash = 0;
|
||||
}
|
||||
|
||||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while (rep1 < length && string[rep1] == string[i])
|
||||
{
|
||||
++rep1;
|
||||
++reps;
|
||||
}
|
||||
|
||||
c = string[i];
|
||||
if (reps > repeat_count_threshold)
|
||||
{
|
||||
if (in_control_form || in_literal_form)
|
||||
{
|
||||
if (in_control_form)
|
||||
fputs_filtered (")", stream);
|
||||
fputs_filtered ("\"//", stream);
|
||||
in_control_form = in_literal_form = 0;
|
||||
}
|
||||
chill_printchar (c, stream);
|
||||
fprintf_filtered (stream, "<repeats %u times>", reps);
|
||||
i = rep1 - 1;
|
||||
things_printed += repeat_count_threshold;
|
||||
need_slashslash = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!in_literal_form && !in_control_form)
|
||||
fputs_filtered ("\"", stream);
|
||||
if (PRINT_LITERAL_FORM (c))
|
||||
{
|
||||
if (!in_literal_form)
|
||||
{
|
||||
if (in_control_form)
|
||||
{
|
||||
fputs_filtered (")", stream);
|
||||
in_control_form = 0;
|
||||
}
|
||||
in_literal_form = 1;
|
||||
}
|
||||
fprintf_filtered (stream, "%c", c);
|
||||
if (c == '"' || c == '^')
|
||||
/* duplicate this one as must be done at input */
|
||||
fprintf_filtered (stream, "%c", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!in_control_form)
|
||||
{
|
||||
if (in_literal_form)
|
||||
{
|
||||
in_literal_form = 0;
|
||||
}
|
||||
fputs_filtered ("^(", stream);
|
||||
in_control_form = 1;
|
||||
}
|
||||
else
|
||||
fprintf_filtered (stream, ",");
|
||||
c = c & 0xff;
|
||||
fprintf_filtered (stream, "%u", (unsigned int) c);
|
||||
}
|
||||
++things_printed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the quotes if necessary. */
|
||||
if (in_control_form)
|
||||
{
|
||||
fputs_filtered (")", stream);
|
||||
}
|
||||
if (in_literal_form || in_control_form)
|
||||
{
|
||||
fputs_filtered ("\"", stream);
|
||||
}
|
||||
if (force_ellipses || (i < length))
|
||||
{
|
||||
fputs_filtered ("...", stream);
|
||||
}
|
||||
}
|
||||
|
||||
static struct type *
|
||||
chill_create_fundamental_type (struct objfile *objfile, int typeid)
|
||||
{
|
||||
register struct type *type = NULL;
|
||||
|
||||
switch (typeid)
|
||||
{
|
||||
default:
|
||||
/* FIXME: For now, if we are asked to produce a type not in this
|
||||
language, create the equivalent of a C integer type with the
|
||||
name "<?type?>". When all the dust settles from the type
|
||||
reconstruction work, this should probably become an error. */
|
||||
type = init_type (TYPE_CODE_INT, 2, 0, "<?type?>", objfile);
|
||||
warning ("internal error: no chill fundamental type %d", typeid);
|
||||
break;
|
||||
case FT_VOID:
|
||||
/* FIXME: Currently the GNU Chill compiler emits some DWARF entries for
|
||||
typedefs, unrelated to anything directly in the code being compiled,
|
||||
that have some FT_VOID types. Just fake it for now. */
|
||||
type = init_type (TYPE_CODE_VOID, 0, 0, "<?VOID?>", objfile);
|
||||
break;
|
||||
case FT_BOOLEAN:
|
||||
type = init_type (TYPE_CODE_BOOL, 1, TYPE_FLAG_UNSIGNED, "BOOL", objfile);
|
||||
break;
|
||||
case FT_CHAR:
|
||||
type = init_type (TYPE_CODE_CHAR, 1, TYPE_FLAG_UNSIGNED, "CHAR", objfile);
|
||||
break;
|
||||
case FT_SIGNED_CHAR:
|
||||
type = init_type (TYPE_CODE_INT, 1, 0, "BYTE", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_CHAR:
|
||||
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "UBYTE", objfile);
|
||||
break;
|
||||
case FT_SHORT: /* Chill ints are 2 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 2, 0, "INT", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_SHORT: /* Chill ints are 2 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, "UINT", objfile);
|
||||
break;
|
||||
case FT_INTEGER: /* FIXME? */
|
||||
case FT_SIGNED_INTEGER: /* FIXME? */
|
||||
case FT_LONG: /* Chill longs are 4 bytes */
|
||||
case FT_SIGNED_LONG: /* Chill longs are 4 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 4, 0, "LONG", objfile);
|
||||
break;
|
||||
case FT_UNSIGNED_INTEGER: /* FIXME? */
|
||||
case FT_UNSIGNED_LONG: /* Chill longs are 4 bytes */
|
||||
type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_UNSIGNED, "ULONG", objfile);
|
||||
break;
|
||||
case FT_FLOAT:
|
||||
type = init_type (TYPE_CODE_FLT, 4, 0, "REAL", objfile);
|
||||
break;
|
||||
case FT_DBL_PREC_FLOAT:
|
||||
type = init_type (TYPE_CODE_FLT, 8, 0, "LONG_REAL", objfile);
|
||||
break;
|
||||
}
|
||||
return (type);
|
||||
}
|
||||
|
||||
|
||||
/* Table of operators and their precedences for printing expressions. */
|
||||
|
||||
static const struct op_print chill_op_print_tab[] =
|
||||
{
|
||||
{"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
|
||||
{"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
|
||||
{"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
|
||||
{"MOD", BINOP_MOD, PREC_MUL, 0},
|
||||
{"REM", BINOP_REM, PREC_MUL, 0},
|
||||
{"SIZE", UNOP_SIZEOF, PREC_BUILTIN_FUNCTION, 0},
|
||||
{"LOWER", UNOP_LOWER, PREC_BUILTIN_FUNCTION, 0},
|
||||
{"UPPER", UNOP_UPPER, PREC_BUILTIN_FUNCTION, 0},
|
||||
{"CARD", UNOP_CARD, PREC_BUILTIN_FUNCTION, 0},
|
||||
{"MAX", UNOP_CHMAX, PREC_BUILTIN_FUNCTION, 0},
|
||||
{"MIN", UNOP_CHMIN, PREC_BUILTIN_FUNCTION, 0},
|
||||
{":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
|
||||
{"=", BINOP_EQUAL, PREC_EQUAL, 0},
|
||||
{"/=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
|
||||
{"<=", BINOP_LEQ, PREC_ORDER, 0},
|
||||
{">=", BINOP_GEQ, PREC_ORDER, 0},
|
||||
{">", BINOP_GTR, PREC_ORDER, 0},
|
||||
{"<", BINOP_LESS, PREC_ORDER, 0},
|
||||
{"+", BINOP_ADD, PREC_ADD, 0},
|
||||
{"-", BINOP_SUB, PREC_ADD, 0},
|
||||
{"*", BINOP_MUL, PREC_MUL, 0},
|
||||
{"/", BINOP_DIV, PREC_MUL, 0},
|
||||
{"//", BINOP_CONCAT, PREC_PREFIX, 0}, /* FIXME: precedence? */
|
||||
{"-", UNOP_NEG, PREC_PREFIX, 0},
|
||||
{"->", UNOP_IND, PREC_SUFFIX, 1},
|
||||
{"->", UNOP_ADDR, PREC_PREFIX, 0},
|
||||
{":", BINOP_RANGE, PREC_ASSIGN, 0},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* The built-in types of Chill. */
|
||||
|
||||
struct type *builtin_type_chill_bool;
|
||||
struct type *builtin_type_chill_char;
|
||||
struct type *builtin_type_chill_long;
|
||||
struct type *builtin_type_chill_ulong;
|
||||
struct type *builtin_type_chill_real;
|
||||
|
||||
struct type **CONST_PTR (chill_builtin_types[]) =
|
||||
{
|
||||
&builtin_type_chill_bool,
|
||||
&builtin_type_chill_char,
|
||||
&builtin_type_chill_long,
|
||||
&builtin_type_chill_ulong,
|
||||
&builtin_type_chill_real,
|
||||
0
|
||||
};
|
||||
|
||||
/* Calculate LOWER or UPPER of TYPE.
|
||||
Returns the result as an integer.
|
||||
*RESULT_TYPE is the appropriate type for the result. */
|
||||
|
||||
LONGEST
|
||||
type_lower_upper (enum exp_opcode op, /* Either UNOP_LOWER or UNOP_UPPER */
|
||||
struct type *type, struct type **result_type)
|
||||
{
|
||||
LONGEST low, high;
|
||||
*result_type = type;
|
||||
CHECK_TYPEDEF (type);
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_STRUCT:
|
||||
*result_type = builtin_type_int;
|
||||
if (chill_varying_type (type))
|
||||
return type_lower_upper (op, TYPE_FIELD_TYPE (type, 1), result_type);
|
||||
break;
|
||||
case TYPE_CODE_ARRAY:
|
||||
case TYPE_CODE_BITSTRING:
|
||||
case TYPE_CODE_STRING:
|
||||
type = TYPE_FIELD_TYPE (type, 0); /* Get index type */
|
||||
|
||||
/* ... fall through ... */
|
||||
case TYPE_CODE_RANGE:
|
||||
*result_type = TYPE_TARGET_TYPE (type);
|
||||
return op == UNOP_LOWER ? TYPE_LOW_BOUND (type) : TYPE_HIGH_BOUND (type);
|
||||
|
||||
case TYPE_CODE_ENUM:
|
||||
case TYPE_CODE_BOOL:
|
||||
case TYPE_CODE_INT:
|
||||
case TYPE_CODE_CHAR:
|
||||
if (get_discrete_bounds (type, &low, &high) >= 0)
|
||||
{
|
||||
*result_type = type;
|
||||
return op == UNOP_LOWER ? low : high;
|
||||
}
|
||||
break;
|
||||
case TYPE_CODE_UNDEF:
|
||||
case TYPE_CODE_PTR:
|
||||
case TYPE_CODE_UNION:
|
||||
case TYPE_CODE_FUNC:
|
||||
case TYPE_CODE_FLT:
|
||||
case TYPE_CODE_VOID:
|
||||
case TYPE_CODE_SET:
|
||||
case TYPE_CODE_ERROR:
|
||||
case TYPE_CODE_MEMBER:
|
||||
case TYPE_CODE_METHOD:
|
||||
case TYPE_CODE_REF:
|
||||
case TYPE_CODE_COMPLEX:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
error ("unknown mode for LOWER/UPPER builtin");
|
||||
}
|
||||
|
||||
static struct value *
|
||||
value_chill_length (struct value *val)
|
||||
{
|
||||
LONGEST tmp;
|
||||
struct type *type = VALUE_TYPE (val);
|
||||
struct type *ttype;
|
||||
CHECK_TYPEDEF (type);
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
case TYPE_CODE_BITSTRING:
|
||||
case TYPE_CODE_STRING:
|
||||
tmp = type_lower_upper (UNOP_UPPER, type, &ttype)
|
||||
- type_lower_upper (UNOP_LOWER, type, &ttype) + 1;
|
||||
break;
|
||||
case TYPE_CODE_STRUCT:
|
||||
if (chill_varying_type (type))
|
||||
{
|
||||
tmp = unpack_long (TYPE_FIELD_TYPE (type, 0), VALUE_CONTENTS (val));
|
||||
break;
|
||||
}
|
||||
/* ... else fall through ... */
|
||||
default:
|
||||
error ("bad argument to LENGTH builtin");
|
||||
}
|
||||
return value_from_longest (builtin_type_int, tmp);
|
||||
}
|
||||
|
||||
static struct value *
|
||||
value_chill_card (struct value *val)
|
||||
{
|
||||
LONGEST tmp = 0;
|
||||
struct type *type = VALUE_TYPE (val);
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_SET)
|
||||
{
|
||||
struct type *range_type = TYPE_INDEX_TYPE (type);
|
||||
LONGEST lower_bound, upper_bound;
|
||||
int i;
|
||||
|
||||
get_discrete_bounds (range_type, &lower_bound, &upper_bound);
|
||||
for (i = lower_bound; i <= upper_bound; i++)
|
||||
if (value_bit_index (type, VALUE_CONTENTS (val), i) > 0)
|
||||
tmp++;
|
||||
}
|
||||
else
|
||||
error ("bad argument to CARD builtin");
|
||||
|
||||
return value_from_longest (builtin_type_int, tmp);
|
||||
}
|
||||
|
||||
static struct value *
|
||||
value_chill_max_min (enum exp_opcode op, struct value *val)
|
||||
{
|
||||
LONGEST tmp = 0;
|
||||
struct type *type = VALUE_TYPE (val);
|
||||
struct type *elttype;
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_SET)
|
||||
{
|
||||
LONGEST lower_bound, upper_bound;
|
||||
int i, empty = 1;
|
||||
|
||||
elttype = TYPE_INDEX_TYPE (type);
|
||||
CHECK_TYPEDEF (elttype);
|
||||
get_discrete_bounds (elttype, &lower_bound, &upper_bound);
|
||||
|
||||
if (op == UNOP_CHMAX)
|
||||
{
|
||||
for (i = upper_bound; i >= lower_bound; i--)
|
||||
{
|
||||
if (value_bit_index (type, VALUE_CONTENTS (val), i) > 0)
|
||||
{
|
||||
tmp = i;
|
||||
empty = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = lower_bound; i <= upper_bound; i++)
|
||||
{
|
||||
if (value_bit_index (type, VALUE_CONTENTS (val), i) > 0)
|
||||
{
|
||||
tmp = i;
|
||||
empty = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty)
|
||||
error ("%s for empty powerset", op == UNOP_CHMAX ? "MAX" : "MIN");
|
||||
}
|
||||
else
|
||||
error ("bad argument to %s builtin", op == UNOP_CHMAX ? "MAX" : "MIN");
|
||||
|
||||
return value_from_longest (TYPE_CODE (elttype) == TYPE_CODE_RANGE
|
||||
? TYPE_TARGET_TYPE (elttype)
|
||||
: elttype,
|
||||
tmp);
|
||||
}
|
||||
|
||||
static struct value *
|
||||
evaluate_subexp_chill (struct type *expect_type,
|
||||
register struct expression *exp, register int *pos,
|
||||
enum noside noside)
|
||||
{
|
||||
int pc = *pos;
|
||||
struct type *type;
|
||||
int tem, nargs;
|
||||
struct value *arg1;
|
||||
struct value **argvec;
|
||||
enum exp_opcode op = exp->elts[*pos].opcode;
|
||||
switch (op)
|
||||
{
|
||||
case MULTI_SUBSCRIPT:
|
||||
if (noside == EVAL_SKIP)
|
||||
break;
|
||||
(*pos) += 3;
|
||||
nargs = longest_to_int (exp->elts[pc + 1].longconst);
|
||||
arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
|
||||
type = check_typedef (VALUE_TYPE (arg1));
|
||||
|
||||
if (nargs == 1 && TYPE_CODE (type) == TYPE_CODE_INT)
|
||||
{
|
||||
/* Looks like string repetition. */
|
||||
struct value *string = evaluate_subexp_with_coercion (exp, pos,
|
||||
noside);
|
||||
return value_concat (arg1, string);
|
||||
}
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_PTR:
|
||||
type = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
if (!type || TYPE_CODE (type) != TYPE_CODE_FUNC)
|
||||
error ("reference value used as function");
|
||||
/* ... fall through ... */
|
||||
case TYPE_CODE_FUNC:
|
||||
/* It's a function call. */
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
break;
|
||||
|
||||
/* Allocate arg vector, including space for the function to be
|
||||
called in argvec[0] and a terminating NULL */
|
||||
argvec = (struct value **) alloca (sizeof (struct value *)
|
||||
* (nargs + 2));
|
||||
argvec[0] = arg1;
|
||||
tem = 1;
|
||||
for (; tem <= nargs && tem <= TYPE_NFIELDS (type); tem++)
|
||||
{
|
||||
argvec[tem]
|
||||
= evaluate_subexp_chill (TYPE_FIELD_TYPE (type, tem - 1),
|
||||
exp, pos, noside);
|
||||
}
|
||||
for (; tem <= nargs; tem++)
|
||||
argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
|
||||
argvec[tem] = 0; /* signal end of arglist */
|
||||
|
||||
return call_function_by_hand (argvec[0], nargs, argvec + 1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
while (nargs-- > 0)
|
||||
{
|
||||
struct value *index = evaluate_subexp_with_coercion (exp, pos,
|
||||
noside);
|
||||
arg1 = value_subscript (arg1, index);
|
||||
}
|
||||
return (arg1);
|
||||
|
||||
case UNOP_LOWER:
|
||||
case UNOP_UPPER:
|
||||
(*pos)++;
|
||||
if (noside == EVAL_SKIP)
|
||||
{
|
||||
(*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos, EVAL_SKIP);
|
||||
goto nosideret;
|
||||
}
|
||||
arg1 = (*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos,
|
||||
EVAL_AVOID_SIDE_EFFECTS);
|
||||
tem = type_lower_upper (op, VALUE_TYPE (arg1), &type);
|
||||
return value_from_longest (type, tem);
|
||||
|
||||
case UNOP_LENGTH:
|
||||
(*pos)++;
|
||||
arg1 = (*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos, noside);
|
||||
return value_chill_length (arg1);
|
||||
|
||||
case UNOP_CARD:
|
||||
(*pos)++;
|
||||
arg1 = (*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos, noside);
|
||||
return value_chill_card (arg1);
|
||||
|
||||
case UNOP_CHMAX:
|
||||
case UNOP_CHMIN:
|
||||
(*pos)++;
|
||||
arg1 = (*exp->language_defn->evaluate_exp) (NULL_TYPE, exp, pos, noside);
|
||||
return value_chill_max_min (op, arg1);
|
||||
|
||||
case BINOP_COMMA:
|
||||
error ("',' operator used in invalid context");
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return evaluate_subexp_standard (expect_type, exp, pos, noside);
|
||||
nosideret:
|
||||
return value_from_longest (builtin_type_long, (LONGEST) 1);
|
||||
}
|
||||
|
||||
const struct language_defn chill_language_defn =
|
||||
{
|
||||
"chill",
|
||||
language_chill,
|
||||
chill_builtin_types,
|
||||
range_check_on,
|
||||
type_check_on,
|
||||
case_sensitive_on,
|
||||
chill_parse, /* parser */
|
||||
chill_error, /* parser error function */
|
||||
evaluate_subexp_chill,
|
||||
chill_printchar, /* print a character constant */
|
||||
chill_printstr, /* function to print a string constant */
|
||||
NULL, /* Function to print a single char */
|
||||
chill_create_fundamental_type, /* Create fundamental type in this language */
|
||||
chill_print_type, /* Print a type using appropriate syntax */
|
||||
chill_val_print, /* Print a value using appropriate syntax */
|
||||
chill_value_print, /* Print a top-levl value */
|
||||
{"", "B'", "", ""}, /* Binary format info */
|
||||
{"O'%lo", "O'", "o", ""}, /* Octal format info */
|
||||
{"D'%ld", "D'", "d", ""}, /* Decimal format info */
|
||||
{"H'%lx", "H'", "x", ""}, /* Hex format info */
|
||||
chill_op_print_tab, /* expression operators for printing */
|
||||
0, /* arrays are first-class (not c-style) */
|
||||
0, /* String lower bound */
|
||||
&builtin_type_chill_char, /* Type of string elements */
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
/* Initialization for Chill */
|
||||
|
||||
void
|
||||
_initialize_chill_language (void)
|
||||
{
|
||||
builtin_type_chill_bool =
|
||||
init_type (TYPE_CODE_BOOL, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"BOOL", (struct objfile *) NULL);
|
||||
builtin_type_chill_char =
|
||||
init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"CHAR", (struct objfile *) NULL);
|
||||
builtin_type_chill_long =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"LONG", (struct objfile *) NULL);
|
||||
builtin_type_chill_ulong =
|
||||
init_type (TYPE_CODE_INT, TARGET_LONG_BIT / TARGET_CHAR_BIT,
|
||||
TYPE_FLAG_UNSIGNED,
|
||||
"ULONG", (struct objfile *) NULL);
|
||||
builtin_type_chill_real =
|
||||
init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
|
||||
0,
|
||||
"LONG_REAL", (struct objfile *) NULL);
|
||||
|
||||
add_language (&chill_language_defn);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/* Chill language support definitions for GDB, the GNU debugger.
|
||||
Copyright 1992, 1994, 1996, 1998, 1999, 2000
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Forward decls for prototypes */
|
||||
struct value;
|
||||
|
||||
extern int chill_parse (void); /* Defined in ch-exp.y */
|
||||
|
||||
extern void chill_error (char *); /* Defined in ch-exp.y */
|
||||
|
||||
/* Defined in ch-typeprint.c */
|
||||
extern void chill_print_type (struct type *, char *, struct ui_file *, int,
|
||||
int);
|
||||
|
||||
extern int chill_val_print (struct type *, char *, int, CORE_ADDR,
|
||||
struct ui_file *, int, int, int,
|
||||
enum val_prettyprint);
|
||||
|
||||
extern int chill_value_print (struct value *, struct ui_file *,
|
||||
int, enum val_prettyprint);
|
||||
|
||||
extern LONGEST
|
||||
type_lower_upper (enum exp_opcode, struct type *, struct type **);
|
||||
@@ -1,340 +0,0 @@
|
||||
/* Support for printing Chill types for GDB, the GNU debugger.
|
||||
Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 2000
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "obstack.h"
|
||||
#include "bfd.h" /* Binary File Description */
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "value.h"
|
||||
#include "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "language.h"
|
||||
#include "ch-lang.h"
|
||||
#include "typeprint.h"
|
||||
|
||||
#include "gdb_string.h"
|
||||
#include <errno.h>
|
||||
|
||||
static void chill_type_print_base (struct type *, struct ui_file *, int, int);
|
||||
|
||||
void
|
||||
chill_print_type (struct type *type, char *varstring, struct ui_file *stream,
|
||||
int show, int level)
|
||||
{
|
||||
if (varstring != NULL && *varstring != '\0')
|
||||
{
|
||||
fputs_filtered (varstring, stream);
|
||||
fputs_filtered (" ", stream);
|
||||
}
|
||||
chill_type_print_base (type, stream, show, level);
|
||||
}
|
||||
|
||||
/* Print the name of the type (or the ultimate pointer target,
|
||||
function value or array element).
|
||||
|
||||
SHOW nonzero means don't print this type as just its name;
|
||||
show its real definition even if it has a name.
|
||||
SHOW zero means print just typename or tag if there is one
|
||||
SHOW negative means abbreviate structure elements.
|
||||
SHOW is decremented for printing of structure elements.
|
||||
|
||||
LEVEL is the depth to indent by.
|
||||
We increase it for some recursive calls. */
|
||||
|
||||
static void
|
||||
chill_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
int level)
|
||||
{
|
||||
register int len;
|
||||
register int i;
|
||||
struct type *index_type;
|
||||
struct type *range_type;
|
||||
LONGEST low_bound;
|
||||
LONGEST high_bound;
|
||||
|
||||
QUIT;
|
||||
|
||||
wrap_here (" ");
|
||||
if (type == NULL)
|
||||
{
|
||||
fputs_filtered ("<type unknown>", stream);
|
||||
return;
|
||||
}
|
||||
|
||||
/* When SHOW is zero or less, and there is a valid type name, then always
|
||||
just print the type name directly from the type. */
|
||||
|
||||
if ((show <= 0) && (TYPE_NAME (type) != NULL))
|
||||
{
|
||||
fputs_filtered (TYPE_NAME (type), stream);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF)
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
|
||||
break;
|
||||
case TYPE_CODE_PTR:
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
|
||||
{
|
||||
fprintf_filtered (stream,
|
||||
TYPE_NAME (type) ? TYPE_NAME (type) : "PTR");
|
||||
break;
|
||||
}
|
||||
fprintf_filtered (stream, "REF ");
|
||||
chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_BOOL:
|
||||
/* FIXME: we should probably just print the TYPE_NAME, in case
|
||||
anyone ever fixes the compiler to give us the real names
|
||||
in the presence of the chill equivalent of typedef (assuming
|
||||
there is one). */
|
||||
fprintf_filtered (stream,
|
||||
TYPE_NAME (type) ? TYPE_NAME (type) : "BOOL");
|
||||
break;
|
||||
|
||||
case TYPE_CODE_ARRAY:
|
||||
fputs_filtered ("ARRAY (", stream);
|
||||
range_type = TYPE_FIELD_TYPE (type, 0);
|
||||
if (TYPE_CODE (range_type) != TYPE_CODE_RANGE)
|
||||
chill_print_type (range_type, "", stream, 0, level);
|
||||
else
|
||||
{
|
||||
index_type = TYPE_TARGET_TYPE (range_type);
|
||||
low_bound = TYPE_FIELD_BITPOS (range_type, 0);
|
||||
high_bound = TYPE_FIELD_BITPOS (range_type, 1);
|
||||
print_type_scalar (index_type, low_bound, stream);
|
||||
fputs_filtered (":", stream);
|
||||
print_type_scalar (index_type, high_bound, stream);
|
||||
}
|
||||
fputs_filtered (") ", stream);
|
||||
chill_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, level);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_BITSTRING:
|
||||
fprintf_filtered (stream, "BOOLS (%d)",
|
||||
TYPE_FIELD_BITPOS (TYPE_FIELD_TYPE (type, 0), 1) + 1);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_SET:
|
||||
fputs_filtered ("POWERSET ", stream);
|
||||
chill_print_type (TYPE_INDEX_TYPE (type), "", stream,
|
||||
show - 1, level);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_STRING:
|
||||
range_type = TYPE_FIELD_TYPE (type, 0);
|
||||
index_type = TYPE_TARGET_TYPE (range_type);
|
||||
high_bound = TYPE_FIELD_BITPOS (range_type, 1);
|
||||
fputs_filtered ("CHARS (", stream);
|
||||
print_type_scalar (index_type, high_bound + 1, stream);
|
||||
fputs_filtered (")", stream);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_MEMBER:
|
||||
fprintf_filtered (stream, "MEMBER ");
|
||||
chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
|
||||
break;
|
||||
case TYPE_CODE_REF:
|
||||
fprintf_filtered (stream, "/*LOC*/ ");
|
||||
chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
|
||||
break;
|
||||
case TYPE_CODE_FUNC:
|
||||
fprintf_filtered (stream, "PROC (");
|
||||
len = TYPE_NFIELDS (type);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
struct type *param_type = TYPE_FIELD_TYPE (type, i);
|
||||
if (i > 0)
|
||||
{
|
||||
fputs_filtered (", ", stream);
|
||||
wrap_here (" ");
|
||||
}
|
||||
if (TYPE_CODE (param_type) == TYPE_CODE_REF)
|
||||
{
|
||||
chill_type_print_base (TYPE_TARGET_TYPE (param_type),
|
||||
stream, 0, level);
|
||||
fputs_filtered (" LOC", stream);
|
||||
}
|
||||
else
|
||||
chill_type_print_base (param_type, stream, show, level);
|
||||
}
|
||||
fprintf_filtered (stream, ")");
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
|
||||
{
|
||||
fputs_filtered (" RETURNS (", stream);
|
||||
chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
|
||||
fputs_filtered (")", stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_STRUCT:
|
||||
if (chill_varying_type (type))
|
||||
{
|
||||
chill_type_print_base (TYPE_FIELD_TYPE (type, 1),
|
||||
stream, 0, level);
|
||||
fputs_filtered (" VARYING", stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "STRUCT ");
|
||||
|
||||
fprintf_filtered (stream, "(\n");
|
||||
if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
|
||||
{
|
||||
if (TYPE_STUB (type))
|
||||
{
|
||||
fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintfi_filtered (level + 4, stream, "<no data fields>\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = TYPE_NFIELDS (type);
|
||||
for (i = TYPE_N_BASECLASSES (type); i < len; i++)
|
||||
{
|
||||
struct type *field_type = TYPE_FIELD_TYPE (type, i);
|
||||
QUIT;
|
||||
print_spaces_filtered (level + 4, stream);
|
||||
if (TYPE_CODE (field_type) == TYPE_CODE_UNION)
|
||||
{
|
||||
int j; /* variant number */
|
||||
fputs_filtered ("CASE OF\n", stream);
|
||||
for (j = 0; j < TYPE_NFIELDS (field_type); j++)
|
||||
{
|
||||
int k; /* variant field index */
|
||||
struct type *variant_type
|
||||
= TYPE_FIELD_TYPE (field_type, j);
|
||||
int var_len = TYPE_NFIELDS (variant_type);
|
||||
print_spaces_filtered (level + 4, stream);
|
||||
if (strcmp (TYPE_FIELD_NAME (field_type, j),
|
||||
"else") == 0)
|
||||
fputs_filtered ("ELSE\n", stream);
|
||||
else
|
||||
fputs_filtered (":\n", stream);
|
||||
if (TYPE_CODE (variant_type) != TYPE_CODE_STRUCT)
|
||||
error ("variant record confusion");
|
||||
for (k = 0; k < var_len; k++)
|
||||
{
|
||||
print_spaces_filtered (level + 8, stream);
|
||||
chill_print_type (TYPE_FIELD_TYPE (variant_type, k),
|
||||
TYPE_FIELD_NAME (variant_type, k),
|
||||
stream, show - 1, level + 8);
|
||||
if (k < (var_len - 1))
|
||||
fputs_filtered (",", stream);
|
||||
fputs_filtered ("\n", stream);
|
||||
}
|
||||
}
|
||||
print_spaces_filtered (level + 4, stream);
|
||||
fputs_filtered ("ESAC", stream);
|
||||
}
|
||||
else
|
||||
chill_print_type (field_type,
|
||||
TYPE_FIELD_NAME (type, i),
|
||||
stream, show - 1, level + 4);
|
||||
if (i < (len - 1))
|
||||
{
|
||||
fputs_filtered (",", stream);
|
||||
}
|
||||
fputs_filtered ("\n", stream);
|
||||
}
|
||||
}
|
||||
fprintfi_filtered (level, stream, ")");
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_RANGE:
|
||||
{
|
||||
struct type *target = TYPE_TARGET_TYPE (type);
|
||||
if (target && TYPE_NAME (target))
|
||||
fputs_filtered (TYPE_NAME (target), stream);
|
||||
else
|
||||
fputs_filtered ("RANGE", stream);
|
||||
if (target == NULL)
|
||||
target = builtin_type_long;
|
||||
fputs_filtered (" (", stream);
|
||||
print_type_scalar (target, TYPE_LOW_BOUND (type), stream);
|
||||
fputs_filtered (":", stream);
|
||||
print_type_scalar (target, TYPE_HIGH_BOUND (type), stream);
|
||||
fputs_filtered (")", stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_ENUM:
|
||||
{
|
||||
register int lastval = 0;
|
||||
fprintf_filtered (stream, "SET (");
|
||||
len = TYPE_NFIELDS (type);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
QUIT;
|
||||
if (i)
|
||||
fprintf_filtered (stream, ", ");
|
||||
wrap_here (" ");
|
||||
fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
|
||||
if (lastval != TYPE_FIELD_BITPOS (type, i))
|
||||
{
|
||||
fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i));
|
||||
lastval = TYPE_FIELD_BITPOS (type, i);
|
||||
}
|
||||
lastval++;
|
||||
}
|
||||
fprintf_filtered (stream, ")");
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_VOID:
|
||||
case TYPE_CODE_UNDEF:
|
||||
case TYPE_CODE_ERROR:
|
||||
case TYPE_CODE_UNION:
|
||||
case TYPE_CODE_METHOD:
|
||||
error ("missing language support in chill_type_print_base");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Handle types not explicitly handled by the other cases,
|
||||
such as fundamental types. For these, just print whatever
|
||||
the type name is, as recorded in the type itself. If there
|
||||
is no type name, then complain. */
|
||||
|
||||
if (TYPE_NAME (type) != NULL)
|
||||
{
|
||||
fputs_filtered (TYPE_NAME (type), stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
error ("Unrecognized type code (%d) in symbol table.",
|
||||
TYPE_CODE (type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,605 +0,0 @@
|
||||
/* Support for printing Chill values for GDB, the GNU debugger.
|
||||
Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "obstack.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "valprint.h"
|
||||
#include "expression.h"
|
||||
#include "value.h"
|
||||
#include "language.h"
|
||||
#include "demangle.h"
|
||||
#include "c-lang.h" /* For c_val_print */
|
||||
#include "typeprint.h"
|
||||
#include "ch-lang.h"
|
||||
#include "annotate.h"
|
||||
|
||||
static void chill_print_value_fields (struct type *, char *,
|
||||
struct ui_file *, int, int,
|
||||
enum val_prettyprint, struct type **);
|
||||
|
||||
static void chill_print_type_scalar (struct type *, LONGEST,
|
||||
struct ui_file *);
|
||||
|
||||
static void chill_val_print_array_elements (struct type *, char *,
|
||||
CORE_ADDR, struct ui_file *,
|
||||
int, int, int,
|
||||
enum val_prettyprint);
|
||||
|
||||
|
||||
/* Print integral scalar data VAL, of type TYPE, onto stdio stream STREAM.
|
||||
Used to print data from type structures in a specified type. For example,
|
||||
array bounds may be characters or booleans in some languages, and this
|
||||
allows the ranges to be printed in their "natural" form rather than as
|
||||
decimal integer values. */
|
||||
|
||||
static void
|
||||
chill_print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
|
||||
{
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_RANGE:
|
||||
if (TYPE_TARGET_TYPE (type))
|
||||
{
|
||||
chill_print_type_scalar (TYPE_TARGET_TYPE (type), val, stream);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case TYPE_CODE_UNDEF:
|
||||
case TYPE_CODE_PTR:
|
||||
case TYPE_CODE_ARRAY:
|
||||
case TYPE_CODE_STRUCT:
|
||||
case TYPE_CODE_UNION:
|
||||
case TYPE_CODE_ENUM:
|
||||
case TYPE_CODE_FUNC:
|
||||
case TYPE_CODE_INT:
|
||||
case TYPE_CODE_FLT:
|
||||
case TYPE_CODE_VOID:
|
||||
case TYPE_CODE_SET:
|
||||
case TYPE_CODE_STRING:
|
||||
case TYPE_CODE_BITSTRING:
|
||||
case TYPE_CODE_ERROR:
|
||||
case TYPE_CODE_MEMBER:
|
||||
case TYPE_CODE_METHOD:
|
||||
case TYPE_CODE_REF:
|
||||
case TYPE_CODE_CHAR:
|
||||
case TYPE_CODE_BOOL:
|
||||
case TYPE_CODE_COMPLEX:
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
print_type_scalar (type, val, stream);
|
||||
}
|
||||
|
||||
/* Print the elements of an array.
|
||||
Similar to val_print_array_elements, but prints
|
||||
element indexes (in Chill syntax). */
|
||||
|
||||
static void
|
||||
chill_val_print_array_elements (struct type *type, char *valaddr,
|
||||
CORE_ADDR address, struct ui_file *stream,
|
||||
int format, int deref_ref, int recurse,
|
||||
enum val_prettyprint pretty)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int things_printed = 0;
|
||||
unsigned len;
|
||||
struct type *elttype;
|
||||
struct type *range_type = TYPE_FIELD_TYPE (type, 0);
|
||||
struct type *index_type = TYPE_TARGET_TYPE (range_type);
|
||||
unsigned eltlen;
|
||||
/* Position of the array element we are examining to see
|
||||
whether it is repeated. */
|
||||
unsigned int rep1;
|
||||
/* Number of repetitions we have detected so far. */
|
||||
unsigned int reps;
|
||||
LONGEST low_bound = TYPE_FIELD_BITPOS (range_type, 0);
|
||||
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
eltlen = TYPE_LENGTH (elttype);
|
||||
len = TYPE_LENGTH (type) / eltlen;
|
||||
|
||||
annotate_array_section_begin (i, elttype);
|
||||
|
||||
for (; i < len && things_printed < print_max; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
if (prettyprint_arrays)
|
||||
{
|
||||
fprintf_filtered (stream, ",\n");
|
||||
print_spaces_filtered (2 + 2 * recurse, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, ", ");
|
||||
}
|
||||
}
|
||||
wrap_here (n_spaces (2 + 2 * recurse));
|
||||
|
||||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while ((rep1 < len) &&
|
||||
!memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen))
|
||||
{
|
||||
++reps;
|
||||
++rep1;
|
||||
}
|
||||
|
||||
fputs_filtered ("(", stream);
|
||||
chill_print_type_scalar (index_type, low_bound + i, stream);
|
||||
if (reps > 1)
|
||||
{
|
||||
fputs_filtered (":", stream);
|
||||
chill_print_type_scalar (index_type, low_bound + i + reps - 1,
|
||||
stream);
|
||||
fputs_filtered ("): ", stream);
|
||||
val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
|
||||
i = rep1 - 1;
|
||||
things_printed += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs_filtered ("): ", stream);
|
||||
val_print (elttype, valaddr + i * eltlen, 0, 0, stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
annotate_elt ();
|
||||
things_printed++;
|
||||
}
|
||||
}
|
||||
annotate_array_section_end ();
|
||||
if (i < len)
|
||||
{
|
||||
fprintf_filtered (stream, "...");
|
||||
}
|
||||
}
|
||||
|
||||
/* Print data of type TYPE located at VALADDR (within GDB), which came from
|
||||
the inferior at address ADDRESS, onto stdio stream STREAM according to
|
||||
FORMAT (a letter or 0 for natural format). The data at VALADDR is in
|
||||
target byte order.
|
||||
|
||||
If the data are a string pointer, returns the number of string characters
|
||||
printed.
|
||||
|
||||
If DEREF_REF is nonzero, then dereference references, otherwise just print
|
||||
them like pointers.
|
||||
|
||||
The PRETTY parameter controls prettyprinting. */
|
||||
|
||||
int
|
||||
chill_val_print (struct type *type, char *valaddr, int embedded_offset,
|
||||
CORE_ADDR address, struct ui_file *stream, int format,
|
||||
int deref_ref, int recurse, enum val_prettyprint pretty)
|
||||
{
|
||||
LONGEST val;
|
||||
unsigned int i = 0; /* Number of characters printed. */
|
||||
struct type *elttype;
|
||||
CORE_ADDR addr;
|
||||
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
|
||||
{
|
||||
if (prettyprint_arrays)
|
||||
{
|
||||
print_spaces_filtered (2 + 2 * recurse, stream);
|
||||
}
|
||||
fprintf_filtered (stream, "[");
|
||||
chill_val_print_array_elements (type, valaddr, address, stream,
|
||||
format, deref_ref, recurse, pretty);
|
||||
fprintf_filtered (stream, "]");
|
||||
}
|
||||
else
|
||||
{
|
||||
error ("unimplemented in chill_val_print; unspecified array length");
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_INT:
|
||||
format = format ? format : output_format;
|
||||
if (format)
|
||||
{
|
||||
print_scalar_formatted (valaddr, type, format, 0, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
val_print_type_code_int (type, valaddr, stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_CHAR:
|
||||
format = format ? format : output_format;
|
||||
if (format)
|
||||
{
|
||||
print_scalar_formatted (valaddr, type, format, 0, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr),
|
||||
stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_FLT:
|
||||
if (format)
|
||||
{
|
||||
print_scalar_formatted (valaddr, type, format, 0, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_floating (valaddr, type, stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_BOOL:
|
||||
format = format ? format : output_format;
|
||||
if (format)
|
||||
{
|
||||
print_scalar_formatted (valaddr, type, format, 0, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Why is this using builtin_type_chill_bool not type? */
|
||||
val = unpack_long (builtin_type_chill_bool, valaddr);
|
||||
fprintf_filtered (stream, val ? "TRUE" : "FALSE");
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_UNDEF:
|
||||
/* This happens (without TYPE_FLAG_STUB set) on systems which don't use
|
||||
dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
|
||||
and no complete type for struct foo in that file. */
|
||||
fprintf_filtered (stream, "<incomplete type>");
|
||||
break;
|
||||
|
||||
case TYPE_CODE_PTR:
|
||||
if (format && format != 's')
|
||||
{
|
||||
print_scalar_formatted (valaddr, type, format, 0, stream);
|
||||
break;
|
||||
}
|
||||
addr = unpack_pointer (type, valaddr);
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
|
||||
/* We assume a NULL pointer is all zeros ... */
|
||||
if (addr == 0)
|
||||
{
|
||||
fputs_filtered ("NULL", stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
|
||||
{
|
||||
/* Try to print what function it points to. */
|
||||
print_address_demangle (addr, stream, demangle);
|
||||
/* Return value is irrelevant except for string pointers. */
|
||||
return (0);
|
||||
}
|
||||
if (addressprint && format != 's')
|
||||
{
|
||||
print_address_numeric (addr, 1, stream);
|
||||
}
|
||||
|
||||
/* For a pointer to char or unsigned char, also print the string
|
||||
pointed to, unless pointer is null. */
|
||||
if (TYPE_LENGTH (elttype) == 1
|
||||
&& TYPE_CODE (elttype) == TYPE_CODE_CHAR
|
||||
&& (format == 0 || format == 's')
|
||||
&& addr != 0
|
||||
&& /* If print_max is UINT_MAX, the alloca below will fail.
|
||||
In that case don't try to print the string. */
|
||||
print_max < UINT_MAX)
|
||||
i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
|
||||
|
||||
/* Return number of characters printed, plus one for the
|
||||
terminating null if we have "reached the end". */
|
||||
return (i + (print_max && i != print_max));
|
||||
break;
|
||||
|
||||
case TYPE_CODE_STRING:
|
||||
i = TYPE_LENGTH (type);
|
||||
LA_PRINT_STRING (stream, valaddr, i, 1, 0);
|
||||
/* Return number of characters printed, plus one for the terminating
|
||||
null if we have "reached the end". */
|
||||
return (i + (print_max && i != print_max));
|
||||
break;
|
||||
|
||||
case TYPE_CODE_BITSTRING:
|
||||
case TYPE_CODE_SET:
|
||||
elttype = TYPE_INDEX_TYPE (type);
|
||||
CHECK_TYPEDEF (elttype);
|
||||
if (TYPE_STUB (elttype))
|
||||
{
|
||||
fprintf_filtered (stream, "<incomplete type>");
|
||||
gdb_flush (stream);
|
||||
break;
|
||||
}
|
||||
{
|
||||
struct type *range = elttype;
|
||||
LONGEST low_bound, high_bound;
|
||||
int i;
|
||||
int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING;
|
||||
int need_comma = 0;
|
||||
|
||||
if (is_bitstring)
|
||||
fputs_filtered ("B'", stream);
|
||||
else
|
||||
fputs_filtered ("[", stream);
|
||||
|
||||
i = get_discrete_bounds (range, &low_bound, &high_bound);
|
||||
maybe_bad_bstring:
|
||||
if (i < 0)
|
||||
{
|
||||
fputs_filtered ("<error value>", stream);
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = low_bound; i <= high_bound; i++)
|
||||
{
|
||||
int element = value_bit_index (type, valaddr, i);
|
||||
if (element < 0)
|
||||
{
|
||||
i = element;
|
||||
goto maybe_bad_bstring;
|
||||
}
|
||||
if (is_bitstring)
|
||||
fprintf_filtered (stream, "%d", element);
|
||||
else if (element)
|
||||
{
|
||||
if (need_comma)
|
||||
fputs_filtered (", ", stream);
|
||||
chill_print_type_scalar (range, (LONGEST) i, stream);
|
||||
need_comma = 1;
|
||||
|
||||
/* Look for a continuous range of true elements. */
|
||||
if (i + 1 <= high_bound && value_bit_index (type, valaddr, ++i))
|
||||
{
|
||||
int j = i; /* j is the upper bound so far of the range */
|
||||
fputs_filtered (":", stream);
|
||||
while (i + 1 <= high_bound
|
||||
&& value_bit_index (type, valaddr, ++i))
|
||||
j = i;
|
||||
chill_print_type_scalar (range, (LONGEST) j, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (is_bitstring)
|
||||
fputs_filtered ("'", stream);
|
||||
else
|
||||
fputs_filtered ("]", stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_STRUCT:
|
||||
if (chill_varying_type (type))
|
||||
{
|
||||
struct type *inner = check_typedef (TYPE_FIELD_TYPE (type, 1));
|
||||
long length = unpack_long (TYPE_FIELD_TYPE (type, 0), valaddr);
|
||||
char *data_addr = valaddr + TYPE_FIELD_BITPOS (type, 1) / 8;
|
||||
|
||||
switch (TYPE_CODE (inner))
|
||||
{
|
||||
case TYPE_CODE_STRING:
|
||||
if (length > TYPE_LENGTH (type) - 2)
|
||||
{
|
||||
fprintf_filtered (stream,
|
||||
"<dynamic length %ld > static length %d> *invalid*",
|
||||
length, TYPE_LENGTH (type));
|
||||
|
||||
/* Don't print the string; doing so might produce a
|
||||
segfault. */
|
||||
return length;
|
||||
}
|
||||
LA_PRINT_STRING (stream, data_addr, length, 1, 0);
|
||||
return length;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
chill_print_value_fields (type, valaddr, stream, format, recurse, pretty,
|
||||
0);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_REF:
|
||||
if (addressprint)
|
||||
{
|
||||
fprintf_filtered (stream, "LOC(");
|
||||
print_address_numeric
|
||||
(extract_address (valaddr, TARGET_PTR_BIT / HOST_CHAR_BIT),
|
||||
1,
|
||||
stream);
|
||||
fprintf_filtered (stream, ")");
|
||||
if (deref_ref)
|
||||
fputs_filtered (": ", stream);
|
||||
}
|
||||
/* De-reference the reference. */
|
||||
if (deref_ref)
|
||||
{
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)
|
||||
{
|
||||
struct value *deref_val =
|
||||
value_at
|
||||
(TYPE_TARGET_TYPE (type),
|
||||
unpack_pointer (lookup_pointer_type (builtin_type_void),
|
||||
valaddr),
|
||||
NULL);
|
||||
val_print (VALUE_TYPE (deref_val),
|
||||
VALUE_CONTENTS (deref_val),
|
||||
0,
|
||||
VALUE_ADDRESS (deref_val), stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
}
|
||||
else
|
||||
fputs_filtered ("???", stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_ENUM:
|
||||
c_val_print (type, valaddr, 0, address, stream, format,
|
||||
deref_ref, recurse, pretty);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_RANGE:
|
||||
if (TYPE_TARGET_TYPE (type))
|
||||
chill_val_print (TYPE_TARGET_TYPE (type), valaddr, 0, address, stream,
|
||||
format, deref_ref, recurse, pretty);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_MEMBER:
|
||||
case TYPE_CODE_UNION:
|
||||
case TYPE_CODE_FUNC:
|
||||
case TYPE_CODE_VOID:
|
||||
case TYPE_CODE_ERROR:
|
||||
default:
|
||||
/* Let's defer printing to the C printer, rather than
|
||||
print an error message. FIXME! */
|
||||
c_val_print (type, valaddr, 0, address, stream, format,
|
||||
deref_ref, recurse, pretty);
|
||||
}
|
||||
gdb_flush (stream);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Mutually recursive subroutines of cplus_print_value and c_val_print to
|
||||
print out a structure's fields: cp_print_value_fields and cplus_print_value.
|
||||
|
||||
TYPE, VALADDR, STREAM, RECURSE, and PRETTY have the
|
||||
same meanings as in cplus_print_value and c_val_print.
|
||||
|
||||
DONT_PRINT is an array of baseclass types that we
|
||||
should not print, or zero if called from top level. */
|
||||
|
||||
static void
|
||||
chill_print_value_fields (struct type *type, char *valaddr,
|
||||
struct ui_file *stream, int format, int recurse,
|
||||
enum val_prettyprint pretty, struct type **dont_print)
|
||||
{
|
||||
int i, len;
|
||||
int fields_seen = 0;
|
||||
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
fprintf_filtered (stream, "[");
|
||||
len = TYPE_NFIELDS (type);
|
||||
if (len == 0)
|
||||
{
|
||||
fprintf_filtered (stream, "<No data fields>");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (fields_seen)
|
||||
{
|
||||
fprintf_filtered (stream, ", ");
|
||||
}
|
||||
fields_seen = 1;
|
||||
if (pretty)
|
||||
{
|
||||
fprintf_filtered (stream, "\n");
|
||||
print_spaces_filtered (2 + 2 * recurse, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
wrap_here (n_spaces (2 + 2 * recurse));
|
||||
}
|
||||
fputs_filtered (".", stream);
|
||||
fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
|
||||
language_chill, DMGL_NO_OPTS);
|
||||
fputs_filtered (": ", stream);
|
||||
if (TYPE_FIELD_PACKED (type, i))
|
||||
{
|
||||
struct value *v;
|
||||
|
||||
/* Bitfields require special handling, especially due to byte
|
||||
order problems. */
|
||||
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
|
||||
unpack_field_as_long (type, valaddr, i));
|
||||
|
||||
chill_val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0,
|
||||
stream, format, 0, recurse + 1, pretty);
|
||||
}
|
||||
else
|
||||
{
|
||||
chill_val_print (TYPE_FIELD_TYPE (type, i),
|
||||
valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0,
|
||||
0, stream, format, 0, recurse + 1, pretty);
|
||||
}
|
||||
}
|
||||
if (pretty)
|
||||
{
|
||||
fprintf_filtered (stream, "\n");
|
||||
print_spaces_filtered (2 * recurse, stream);
|
||||
}
|
||||
}
|
||||
fprintf_filtered (stream, "]");
|
||||
}
|
||||
|
||||
int
|
||||
chill_value_print (struct value *val, struct ui_file *stream, int format,
|
||||
enum val_prettyprint pretty)
|
||||
{
|
||||
struct type *type = VALUE_TYPE (val);
|
||||
struct type *real_type = check_typedef (type);
|
||||
|
||||
/* If it is a pointer, indicate what it points to.
|
||||
|
||||
Print type also if it is a reference. */
|
||||
|
||||
if (TYPE_CODE (real_type) == TYPE_CODE_PTR ||
|
||||
TYPE_CODE (real_type) == TYPE_CODE_REF)
|
||||
{
|
||||
char *valaddr = VALUE_CONTENTS (val);
|
||||
CORE_ADDR addr = unpack_pointer (type, valaddr);
|
||||
if (TYPE_CODE (type) != TYPE_CODE_PTR || addr != 0)
|
||||
{
|
||||
int i;
|
||||
char *name = TYPE_NAME (type);
|
||||
if (name)
|
||||
fputs_filtered (name, stream);
|
||||
else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
|
||||
fputs_filtered ("PTR", stream);
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "(");
|
||||
type_print (type, "", stream, -1);
|
||||
fprintf_filtered (stream, ")");
|
||||
}
|
||||
fprintf_filtered (stream, "(");
|
||||
i = val_print (type, valaddr, 0, VALUE_ADDRESS (val),
|
||||
stream, format, 1, 0, pretty);
|
||||
fprintf_filtered (stream, ")");
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return (val_print (type, VALUE_CONTENTS (val), 0,
|
||||
VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
|
||||
}
|
||||
377
gdb/cli-out.c
377
gdb/cli-out.c
@@ -1,377 +0,0 @@
|
||||
/* Output generating routines for GDB CLI.
|
||||
Copyright 1999, 2000 Free Software Foundation, Inc.
|
||||
Contributed by Cygnus Solutions.
|
||||
Written by Fernando Nasser for Cygnus.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "ui-out.h"
|
||||
#include "cli-out.h"
|
||||
#include "gdb_string.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
/* Convenience macro for allocting typesafe memory. */
|
||||
|
||||
#ifndef XMALLOC
|
||||
#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
|
||||
#endif
|
||||
|
||||
struct ui_out_data
|
||||
{
|
||||
struct ui_file *stream;
|
||||
int suppress_output;
|
||||
};
|
||||
|
||||
/* These are the CLI output functions */
|
||||
|
||||
static void cli_table_begin (struct ui_out *uiout, int nbrofcols,
|
||||
int nr_rows, const char *tblid);
|
||||
static void cli_table_body (struct ui_out *uiout);
|
||||
static void cli_table_end (struct ui_out *uiout);
|
||||
static void cli_table_header (struct ui_out *uiout, int width,
|
||||
enum ui_align alig, const char *col_name,
|
||||
const char *colhdr);
|
||||
static void cli_begin (struct ui_out *uiout, enum ui_out_type type,
|
||||
int level, const char *lstid);
|
||||
static void cli_end (struct ui_out *uiout, enum ui_out_type type, int level);
|
||||
static void cli_field_int (struct ui_out *uiout, int fldno, int width,
|
||||
enum ui_align alig, const char *fldname, int value);
|
||||
static void cli_field_skip (struct ui_out *uiout, int fldno, int width,
|
||||
enum ui_align alig, const char *fldname);
|
||||
static void cli_field_string (struct ui_out *uiout, int fldno, int width,
|
||||
enum ui_align alig, const char *fldname,
|
||||
const char *string);
|
||||
static void cli_field_fmt (struct ui_out *uiout, int fldno,
|
||||
int width, enum ui_align align,
|
||||
const char *fldname, const char *format,
|
||||
va_list args);
|
||||
static void cli_spaces (struct ui_out *uiout, int numspaces);
|
||||
static void cli_text (struct ui_out *uiout, const char *string);
|
||||
static void cli_message (struct ui_out *uiout, int verbosity,
|
||||
const char *format, va_list args);
|
||||
static void cli_wrap_hint (struct ui_out *uiout, char *identstring);
|
||||
static void cli_flush (struct ui_out *uiout);
|
||||
|
||||
/* This is the CLI ui-out implementation functions vector */
|
||||
|
||||
/* FIXME: This can be initialized dynamically after default is set to
|
||||
handle initial output in main.c */
|
||||
|
||||
static struct ui_out_impl cli_ui_out_impl =
|
||||
{
|
||||
cli_table_begin,
|
||||
cli_table_body,
|
||||
cli_table_end,
|
||||
cli_table_header,
|
||||
cli_begin,
|
||||
cli_end,
|
||||
cli_field_int,
|
||||
cli_field_skip,
|
||||
cli_field_string,
|
||||
cli_field_fmt,
|
||||
cli_spaces,
|
||||
cli_text,
|
||||
cli_message,
|
||||
cli_wrap_hint,
|
||||
cli_flush,
|
||||
0, /* Does not need MI hacks (i.e. needs CLI hacks). */
|
||||
};
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
extern void _initialize_cli_out (void);
|
||||
|
||||
static void field_separator (void);
|
||||
|
||||
static void out_field_fmt (struct ui_out *uiout, int fldno,
|
||||
const char *fldname,
|
||||
const char *format,...);
|
||||
|
||||
/* local variables */
|
||||
|
||||
/* (none yet) */
|
||||
|
||||
/* Mark beginning of a table */
|
||||
|
||||
void
|
||||
cli_table_begin (struct ui_out *uiout, int nbrofcols,
|
||||
int nr_rows,
|
||||
const char *tblid)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (nr_rows == 0)
|
||||
data->suppress_output = 1;
|
||||
else
|
||||
/* Only the table suppresses the output and, fortunatly, a table
|
||||
is not a recursive data structure. */
|
||||
gdb_assert (data->suppress_output == 0);
|
||||
}
|
||||
|
||||
/* Mark beginning of a table body */
|
||||
|
||||
void
|
||||
cli_table_body (struct ui_out *uiout)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
/* first, close the table header line */
|
||||
cli_text (uiout, "\n");
|
||||
}
|
||||
|
||||
/* Mark end of a table */
|
||||
|
||||
void
|
||||
cli_table_end (struct ui_out *uiout)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
data->suppress_output = 0;
|
||||
}
|
||||
|
||||
/* Specify table header */
|
||||
|
||||
void
|
||||
cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
|
||||
const char *col_name,
|
||||
const char *colhdr)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
cli_field_string (uiout, 0, width, alignment, 0, colhdr);
|
||||
}
|
||||
|
||||
/* Mark beginning of a list */
|
||||
|
||||
void
|
||||
cli_begin (struct ui_out *uiout,
|
||||
enum ui_out_type type,
|
||||
int level,
|
||||
const char *id)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark end of a list */
|
||||
|
||||
void
|
||||
cli_end (struct ui_out *uiout,
|
||||
enum ui_out_type type,
|
||||
int level)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
}
|
||||
|
||||
/* output an int field */
|
||||
|
||||
void
|
||||
cli_field_int (struct ui_out *uiout, int fldno, int width,
|
||||
enum ui_align alignment,
|
||||
const char *fldname, int value)
|
||||
{
|
||||
char buffer[20]; /* FIXME: how many chars long a %d can become? */
|
||||
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
sprintf (buffer, "%d", value);
|
||||
cli_field_string (uiout, fldno, width, alignment, fldname, buffer);
|
||||
}
|
||||
|
||||
/* used to ommit a field */
|
||||
|
||||
void
|
||||
cli_field_skip (struct ui_out *uiout, int fldno, int width,
|
||||
enum ui_align alignment,
|
||||
const char *fldname)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
cli_field_string (uiout, fldno, width, alignment, fldname, "");
|
||||
}
|
||||
|
||||
/* other specific cli_field_* end up here so alignment and field
|
||||
separators are both handled by cli_field_string */
|
||||
|
||||
void
|
||||
cli_field_string (struct ui_out *uiout,
|
||||
int fldno,
|
||||
int width,
|
||||
enum ui_align align,
|
||||
const char *fldname,
|
||||
const char *string)
|
||||
{
|
||||
int before = 0;
|
||||
int after = 0;
|
||||
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
|
||||
if ((align != ui_noalign) && string)
|
||||
{
|
||||
before = width - strlen (string);
|
||||
if (before <= 0)
|
||||
before = 0;
|
||||
else
|
||||
{
|
||||
if (align == ui_right)
|
||||
after = 0;
|
||||
else if (align == ui_left)
|
||||
{
|
||||
after = before;
|
||||
before = 0;
|
||||
}
|
||||
else
|
||||
/* ui_center */
|
||||
{
|
||||
after = before / 2;
|
||||
before -= after;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (before)
|
||||
ui_out_spaces (uiout, before);
|
||||
if (string)
|
||||
out_field_fmt (uiout, fldno, fldname, "%s", string);
|
||||
if (after)
|
||||
ui_out_spaces (uiout, after);
|
||||
|
||||
if (align != ui_noalign)
|
||||
field_separator ();
|
||||
}
|
||||
|
||||
/* This is the only field function that does not align */
|
||||
|
||||
void
|
||||
cli_field_fmt (struct ui_out *uiout, int fldno,
|
||||
int width, enum ui_align align,
|
||||
const char *fldname,
|
||||
const char *format,
|
||||
va_list args)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
|
||||
vfprintf_filtered (data->stream, format, args);
|
||||
|
||||
if (align != ui_noalign)
|
||||
field_separator ();
|
||||
}
|
||||
|
||||
void
|
||||
cli_spaces (struct ui_out *uiout, int numspaces)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
print_spaces_filtered (numspaces, data->stream);
|
||||
}
|
||||
|
||||
void
|
||||
cli_text (struct ui_out *uiout, const char *string)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
fputs_filtered (string, data->stream);
|
||||
}
|
||||
|
||||
void
|
||||
cli_message (struct ui_out *uiout, int verbosity,
|
||||
const char *format, va_list args)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
if (ui_out_get_verblvl (uiout) >= verbosity)
|
||||
vfprintf_unfiltered (data->stream, format, args);
|
||||
}
|
||||
|
||||
void
|
||||
cli_wrap_hint (struct ui_out *uiout, char *identstring)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
if (data->suppress_output)
|
||||
return;
|
||||
wrap_here (identstring);
|
||||
}
|
||||
|
||||
void
|
||||
cli_flush (struct ui_out *uiout)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
gdb_flush (data->stream);
|
||||
}
|
||||
|
||||
/* local functions */
|
||||
|
||||
/* Like cli_field_fmt, but takes a variable number of args
|
||||
and makes a va_list and does not insert a separator */
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
out_field_fmt (struct ui_out *uiout, int fldno,
|
||||
const char *fldname,
|
||||
const char *format,...)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
vfprintf_filtered (data->stream, format, args);
|
||||
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
/* access to ui_out format private members */
|
||||
|
||||
static void
|
||||
field_separator (void)
|
||||
{
|
||||
struct ui_out_data *data = ui_out_data (uiout);
|
||||
fputc_filtered (' ', data->stream);
|
||||
}
|
||||
|
||||
/* initalize private members at startup */
|
||||
|
||||
struct ui_out *
|
||||
cli_out_new (struct ui_file *stream)
|
||||
{
|
||||
int flags = ui_source_list;
|
||||
|
||||
struct ui_out_data *data = XMALLOC (struct ui_out_data);
|
||||
data->stream = stream;
|
||||
data->suppress_output = 0;
|
||||
return ui_out_new (&cli_ui_out_impl, data, flags);
|
||||
}
|
||||
|
||||
/* standard gdb initialization hook */
|
||||
void
|
||||
_initialize_cli_out (void)
|
||||
{
|
||||
/* nothing needs to be done */
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/* Output generating routines for GDB CLI.
|
||||
Copyright 1999, 2000 Free Software Foundation, Inc.
|
||||
Contributed by Cygnus Solutions.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef CLI_OUT_H
|
||||
#define CLI_OUT_H
|
||||
|
||||
extern struct ui_out *cli_out_new (struct ui_file *stream);
|
||||
|
||||
#endif
|
||||
@@ -1,792 +0,0 @@
|
||||
/* GDB CLI commands.
|
||||
|
||||
Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "completer.h"
|
||||
#include "target.h" /* For baud_rate, remote_debug and remote_timeout */
|
||||
#include "gdb_wait.h" /* For shell escape implementation */
|
||||
#include "gdb_regex.h" /* Used by apropos_command */
|
||||
#include "filenames.h" /* for DOSish file names */
|
||||
|
||||
#include "ui-out.h"
|
||||
|
||||
#include "top.h"
|
||||
#include "cli/cli-decode.h"
|
||||
#include "cli/cli-script.h"
|
||||
#include "cli/cli-setshow.h"
|
||||
#include "cli/cli-cmds.h"
|
||||
|
||||
#ifndef GDBINIT_FILENAME
|
||||
#define GDBINIT_FILENAME ".gdbinit"
|
||||
#endif
|
||||
|
||||
/* From gdb/top.c */
|
||||
|
||||
extern void dont_repeat (void);
|
||||
|
||||
extern void set_verbose (char *, int, struct cmd_list_element *);
|
||||
|
||||
extern void show_history (char *, int);
|
||||
|
||||
extern void set_history (char *, int);
|
||||
|
||||
extern void show_commands (char *, int);
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
static void complete_command (char *, int);
|
||||
|
||||
static void echo_command (char *, int);
|
||||
|
||||
static void pwd_command (char *, int);
|
||||
|
||||
static void show_version (char *, int);
|
||||
|
||||
static void validate_comname (char *);
|
||||
|
||||
static void help_command (char *, int);
|
||||
|
||||
static void show_command (char *, int);
|
||||
|
||||
static void info_command (char *, int);
|
||||
|
||||
static void show_debug (char *, int);
|
||||
|
||||
static void set_debug (char *, int);
|
||||
|
||||
static void show_user (char *, int);
|
||||
|
||||
static void make_command (char *, int);
|
||||
|
||||
static void shell_escape (char *, int);
|
||||
|
||||
void apropos_command (char *, int);
|
||||
|
||||
/* Define all cmd_list_elements. */
|
||||
|
||||
/* Chain containing all defined commands. */
|
||||
|
||||
struct cmd_list_element *cmdlist;
|
||||
|
||||
/* Chain containing all defined info subcommands. */
|
||||
|
||||
struct cmd_list_element *infolist;
|
||||
|
||||
/* Chain containing all defined enable subcommands. */
|
||||
|
||||
struct cmd_list_element *enablelist;
|
||||
|
||||
/* Chain containing all defined disable subcommands. */
|
||||
|
||||
struct cmd_list_element *disablelist;
|
||||
|
||||
/* Chain containing all defined toggle subcommands. */
|
||||
|
||||
struct cmd_list_element *togglelist;
|
||||
|
||||
/* Chain containing all defined stop subcommands. */
|
||||
|
||||
struct cmd_list_element *stoplist;
|
||||
|
||||
/* Chain containing all defined delete subcommands. */
|
||||
|
||||
struct cmd_list_element *deletelist;
|
||||
|
||||
/* Chain containing all defined "enable breakpoint" subcommands. */
|
||||
|
||||
struct cmd_list_element *enablebreaklist;
|
||||
|
||||
/* Chain containing all defined set subcommands */
|
||||
|
||||
struct cmd_list_element *setlist;
|
||||
|
||||
/* Chain containing all defined unset subcommands */
|
||||
|
||||
struct cmd_list_element *unsetlist;
|
||||
|
||||
/* Chain containing all defined show subcommands. */
|
||||
|
||||
struct cmd_list_element *showlist;
|
||||
|
||||
/* Chain containing all defined \"set history\". */
|
||||
|
||||
struct cmd_list_element *sethistlist;
|
||||
|
||||
/* Chain containing all defined \"show history\". */
|
||||
|
||||
struct cmd_list_element *showhistlist;
|
||||
|
||||
/* Chain containing all defined \"unset history\". */
|
||||
|
||||
struct cmd_list_element *unsethistlist;
|
||||
|
||||
/* Chain containing all defined maintenance subcommands. */
|
||||
|
||||
struct cmd_list_element *maintenancelist;
|
||||
|
||||
/* Chain containing all defined "maintenance info" subcommands. */
|
||||
|
||||
struct cmd_list_element *maintenanceinfolist;
|
||||
|
||||
/* Chain containing all defined "maintenance print" subcommands. */
|
||||
|
||||
struct cmd_list_element *maintenanceprintlist;
|
||||
|
||||
struct cmd_list_element *setprintlist;
|
||||
|
||||
struct cmd_list_element *showprintlist;
|
||||
|
||||
struct cmd_list_element *setdebuglist;
|
||||
|
||||
struct cmd_list_element *showdebuglist;
|
||||
|
||||
struct cmd_list_element *setchecklist;
|
||||
|
||||
struct cmd_list_element *showchecklist;
|
||||
|
||||
/* Utility used everywhere when at least one argument is needed and
|
||||
none is supplied. */
|
||||
|
||||
void
|
||||
error_no_arg (char *why)
|
||||
{
|
||||
error ("Argument required (%s).", why);
|
||||
}
|
||||
|
||||
/* The "info" command is defined as a prefix, with allow_unknown = 0.
|
||||
Therefore, its own definition is called only for "info" with no args. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
info_command (char *arg, int from_tty)
|
||||
{
|
||||
printf_unfiltered ("\"info\" must be followed by the name of an info command.\n");
|
||||
help_list (infolist, "info ", -1, gdb_stdout);
|
||||
}
|
||||
|
||||
/* The "show" command with no arguments shows all the settings. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
show_command (char *arg, int from_tty)
|
||||
{
|
||||
cmd_show_list (showlist, from_tty, "");
|
||||
}
|
||||
|
||||
/* Provide documentation on command or list given by COMMAND. FROM_TTY
|
||||
is ignored. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
help_command (char *command, int from_tty)
|
||||
{
|
||||
help_cmd (command, gdb_stdout);
|
||||
}
|
||||
|
||||
/* The "complete" command is used by Emacs to implement completion. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
complete_command (char *arg, int from_tty)
|
||||
{
|
||||
int i;
|
||||
int argpoint;
|
||||
char *completion;
|
||||
|
||||
dont_repeat ();
|
||||
|
||||
if (arg == NULL)
|
||||
arg = "";
|
||||
argpoint = strlen (arg);
|
||||
|
||||
for (completion = line_completion_function (arg, i = 0, arg, argpoint);
|
||||
completion;
|
||||
completion = line_completion_function (arg, ++i, arg, argpoint))
|
||||
{
|
||||
printf_unfiltered ("%s\n", completion);
|
||||
xfree (completion);
|
||||
}
|
||||
}
|
||||
|
||||
int is_complete_command (void (*func) (char *args, int from_tty))
|
||||
{
|
||||
return func == complete_command;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
show_version (char *args, int from_tty)
|
||||
{
|
||||
immediate_quit++;
|
||||
print_gdb_version (gdb_stdout);
|
||||
printf_filtered ("\n");
|
||||
immediate_quit--;
|
||||
}
|
||||
|
||||
/* Handle the quit command. */
|
||||
|
||||
void
|
||||
quit_command (char *args, int from_tty)
|
||||
{
|
||||
if (!quit_confirm ())
|
||||
error ("Not confirmed.");
|
||||
quit_force (args, from_tty);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
pwd_command (char *args, int from_tty)
|
||||
{
|
||||
if (args)
|
||||
error ("The \"pwd\" command does not take an argument: %s", args);
|
||||
getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
|
||||
|
||||
if (!STREQ (gdb_dirbuf, current_directory))
|
||||
printf_unfiltered ("Working directory %s\n (canonically %s).\n",
|
||||
current_directory, gdb_dirbuf);
|
||||
else
|
||||
printf_unfiltered ("Working directory %s.\n", current_directory);
|
||||
}
|
||||
|
||||
void
|
||||
cd_command (char *dir, int from_tty)
|
||||
{
|
||||
int len;
|
||||
/* Found something other than leading repetitions of "/..". */
|
||||
int found_real_path;
|
||||
char *p;
|
||||
|
||||
/* If the new directory is absolute, repeat is a no-op; if relative,
|
||||
repeat might be useful but is more likely to be a mistake. */
|
||||
dont_repeat ();
|
||||
|
||||
if (dir == 0)
|
||||
error_no_arg ("new working directory");
|
||||
|
||||
dir = tilde_expand (dir);
|
||||
make_cleanup (xfree, dir);
|
||||
|
||||
if (chdir (dir) < 0)
|
||||
perror_with_name (dir);
|
||||
|
||||
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
|
||||
/* There's too much mess with DOSish names like "d:", "d:.",
|
||||
"d:./foo" etc. Instead of having lots of special #ifdef'ed code,
|
||||
simply get the canonicalized name of the current directory. */
|
||||
dir = getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
|
||||
#endif
|
||||
|
||||
len = strlen (dir);
|
||||
if (IS_DIR_SEPARATOR (dir[len - 1]))
|
||||
{
|
||||
/* Remove the trailing slash unless this is a root directory
|
||||
(including a drive letter on non-Unix systems). */
|
||||
if (!(len == 1) /* "/" */
|
||||
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
|
||||
&& !(len == 3 && dir[1] == ':') /* "d:/" */
|
||||
#endif
|
||||
)
|
||||
len--;
|
||||
}
|
||||
|
||||
dir = savestring (dir, len);
|
||||
if (IS_ABSOLUTE_PATH (dir))
|
||||
current_directory = dir;
|
||||
else
|
||||
{
|
||||
if (IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]))
|
||||
current_directory = concat (current_directory, dir, NULL);
|
||||
else
|
||||
current_directory = concat (current_directory, SLASH_STRING, dir, NULL);
|
||||
xfree (dir);
|
||||
}
|
||||
|
||||
/* Now simplify any occurrences of `.' and `..' in the pathname. */
|
||||
|
||||
found_real_path = 0;
|
||||
for (p = current_directory; *p;)
|
||||
{
|
||||
if (IS_DIR_SEPARATOR (p[0]) && p[1] == '.'
|
||||
&& (p[2] == 0 || IS_DIR_SEPARATOR (p[2])))
|
||||
strcpy (p, p + 2);
|
||||
else if (IS_DIR_SEPARATOR (p[0]) && p[1] == '.' && p[2] == '.'
|
||||
&& (p[3] == 0 || IS_DIR_SEPARATOR (p[3])))
|
||||
{
|
||||
if (found_real_path)
|
||||
{
|
||||
/* Search backwards for the directory just before the "/.."
|
||||
and obliterate it and the "/..". */
|
||||
char *q = p;
|
||||
while (q != current_directory && !IS_DIR_SEPARATOR (q[-1]))
|
||||
--q;
|
||||
|
||||
if (q == current_directory)
|
||||
/* current_directory is
|
||||
a relative pathname ("can't happen"--leave it alone). */
|
||||
++p;
|
||||
else
|
||||
{
|
||||
strcpy (q - 1, p + 3);
|
||||
p = q - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* We are dealing with leading repetitions of "/..", for example
|
||||
"/../..", which is the Mach super-root. */
|
||||
p += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
found_real_path = 1;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
forget_cached_source_info ();
|
||||
|
||||
if (from_tty)
|
||||
pwd_command ((char *) 0, 1);
|
||||
}
|
||||
|
||||
void
|
||||
source_command (char *args, int from_tty)
|
||||
{
|
||||
FILE *stream;
|
||||
struct cleanup *old_cleanups;
|
||||
char *file = args;
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
error ("source command requires pathname of file to source.");
|
||||
}
|
||||
|
||||
file = tilde_expand (file);
|
||||
old_cleanups = make_cleanup (xfree, file);
|
||||
|
||||
stream = fopen (file, FOPEN_RT);
|
||||
if (!stream)
|
||||
{
|
||||
if (from_tty)
|
||||
perror_with_name (file);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
script_from_file (stream, file);
|
||||
|
||||
do_cleanups (old_cleanups);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
echo_command (char *text, int from_tty)
|
||||
{
|
||||
char *p = text;
|
||||
register int c;
|
||||
|
||||
if (text)
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
if (c == '\\')
|
||||
{
|
||||
/* \ at end of argument is used after spaces
|
||||
so they won't be lost. */
|
||||
if (*p == 0)
|
||||
return;
|
||||
|
||||
c = parse_escape (&p);
|
||||
if (c >= 0)
|
||||
printf_filtered ("%c", c);
|
||||
}
|
||||
else
|
||||
printf_filtered ("%c", c);
|
||||
}
|
||||
|
||||
/* Force this output to appear now. */
|
||||
wrap_here ("");
|
||||
gdb_flush (gdb_stdout);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
shell_escape (char *arg, int from_tty)
|
||||
{
|
||||
#ifdef CANT_FORK
|
||||
/* If ARG is NULL, they want an inferior shell, but `system' just
|
||||
reports if the shell is available when passed a NULL arg. */
|
||||
int rc = system (arg ? arg : "");
|
||||
|
||||
if (!arg)
|
||||
arg = "inferior shell";
|
||||
|
||||
if (rc == -1)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", arg,
|
||||
safe_strerror (errno));
|
||||
gdb_flush (gdb_stderr);
|
||||
}
|
||||
else if (rc)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr, "%s exited with status %d\n", arg, rc);
|
||||
gdb_flush (gdb_stderr);
|
||||
}
|
||||
#ifdef GLOBAL_CURDIR
|
||||
/* Make sure to return to the directory GDB thinks it is, in case the
|
||||
shell command we just ran changed it. */
|
||||
chdir (current_directory);
|
||||
#endif
|
||||
#else /* Can fork. */
|
||||
int rc, status, pid;
|
||||
char *p, *user_shell;
|
||||
|
||||
if ((user_shell = (char *) getenv ("SHELL")) == NULL)
|
||||
user_shell = "/bin/sh";
|
||||
|
||||
/* Get the name of the shell for arg0 */
|
||||
if ((p = strrchr (user_shell, '/')) == NULL)
|
||||
p = user_shell;
|
||||
else
|
||||
p++; /* Get past '/' */
|
||||
|
||||
if ((pid = fork ()) == 0)
|
||||
{
|
||||
if (!arg)
|
||||
execl (user_shell, p, 0);
|
||||
else
|
||||
execl (user_shell, p, "-c", arg, 0);
|
||||
|
||||
fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell,
|
||||
safe_strerror (errno));
|
||||
gdb_flush (gdb_stderr);
|
||||
_exit (0177);
|
||||
}
|
||||
|
||||
if (pid != -1)
|
||||
while ((rc = wait (&status)) != pid && rc != -1)
|
||||
;
|
||||
else
|
||||
error ("Fork failed");
|
||||
#endif /* Can fork. */
|
||||
}
|
||||
|
||||
static void
|
||||
make_command (char *arg, int from_tty)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (arg == 0)
|
||||
p = "make";
|
||||
else
|
||||
{
|
||||
p = xmalloc (sizeof ("make ") + strlen (arg));
|
||||
strcpy (p, "make ");
|
||||
strcpy (p + sizeof ("make ") - 1, arg);
|
||||
}
|
||||
|
||||
shell_escape (p, from_tty);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
show_user (char *args, int from_tty)
|
||||
{
|
||||
struct cmd_list_element *c;
|
||||
extern struct cmd_list_element *cmdlist;
|
||||
|
||||
if (args)
|
||||
{
|
||||
c = lookup_cmd (&args, cmdlist, "", 0, 1);
|
||||
if (c->class != class_user)
|
||||
error ("Not a user command.");
|
||||
show_user_1 (c, gdb_stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c = cmdlist; c; c = c->next)
|
||||
{
|
||||
if (c->class == class_user)
|
||||
show_user_1 (c, gdb_stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Search through names of commands and documentations for a certain
|
||||
regular expression.
|
||||
*/
|
||||
void
|
||||
apropos_command (char *searchstr, int from_tty)
|
||||
{
|
||||
extern struct cmd_list_element *cmdlist; /*This is the main command list*/
|
||||
regex_t pattern;
|
||||
char *pattern_fastmap;
|
||||
char errorbuffer[512];
|
||||
pattern_fastmap = xcalloc (256, sizeof (char));
|
||||
if (searchstr == NULL)
|
||||
error("REGEXP string is empty");
|
||||
|
||||
if (regcomp(&pattern,searchstr,REG_ICASE) == 0)
|
||||
{
|
||||
pattern.fastmap=pattern_fastmap;
|
||||
re_compile_fastmap(&pattern);
|
||||
apropos_cmd (gdb_stdout,cmdlist,&pattern,"");
|
||||
}
|
||||
else
|
||||
{
|
||||
regerror(regcomp(&pattern,searchstr,REG_ICASE),NULL,errorbuffer,512);
|
||||
error("Error in regular expression:%s",errorbuffer);
|
||||
}
|
||||
xfree (pattern_fastmap);
|
||||
}
|
||||
|
||||
static void
|
||||
set_debug (char *arg, int from_tty)
|
||||
{
|
||||
printf_unfiltered ("\"set debug\" must be followed by the name of a print subcommand.\n");
|
||||
help_list (setdebuglist, "set debug ", -1, gdb_stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
show_debug (char *args, int from_tty)
|
||||
{
|
||||
cmd_show_list (showdebuglist, from_tty, "");
|
||||
}
|
||||
|
||||
void
|
||||
init_cmd_lists (void)
|
||||
{
|
||||
cmdlist = NULL;
|
||||
infolist = NULL;
|
||||
enablelist = NULL;
|
||||
disablelist = NULL;
|
||||
togglelist = NULL;
|
||||
stoplist = NULL;
|
||||
deletelist = NULL;
|
||||
enablebreaklist = NULL;
|
||||
setlist = NULL;
|
||||
unsetlist = NULL;
|
||||
showlist = NULL;
|
||||
sethistlist = NULL;
|
||||
showhistlist = NULL;
|
||||
unsethistlist = NULL;
|
||||
maintenancelist = NULL;
|
||||
maintenanceinfolist = NULL;
|
||||
maintenanceprintlist = NULL;
|
||||
setprintlist = NULL;
|
||||
showprintlist = NULL;
|
||||
setchecklist = NULL;
|
||||
showchecklist = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
init_cli_cmds (void)
|
||||
{
|
||||
struct cmd_list_element *c;
|
||||
|
||||
/* Define the classes of commands.
|
||||
They will appear in the help list in the reverse of this order. */
|
||||
|
||||
add_cmd ("internals", class_maintenance, NULL,
|
||||
"Maintenance commands.\n\
|
||||
Some gdb commands are provided just for use by gdb maintainers.\n\
|
||||
These commands are subject to frequent change, and may not be as\n\
|
||||
well documented as user commands.",
|
||||
&cmdlist);
|
||||
add_cmd ("obscure", class_obscure, NULL, "Obscure features.", &cmdlist);
|
||||
add_cmd ("aliases", class_alias, NULL, "Aliases of other commands.", &cmdlist);
|
||||
add_cmd ("user-defined", class_user, NULL, "User-defined commands.\n\
|
||||
The commands in this class are those defined by the user.\n\
|
||||
Use the \"define\" command to define a command.", &cmdlist);
|
||||
add_cmd ("support", class_support, NULL, "Support facilities.", &cmdlist);
|
||||
if (!dbx_commands)
|
||||
add_cmd ("status", class_info, NULL, "Status inquiries.", &cmdlist);
|
||||
add_cmd ("files", class_files, NULL, "Specifying and examining files.", &cmdlist);
|
||||
add_cmd ("breakpoints", class_breakpoint, NULL, "Making program stop at certain points.", &cmdlist);
|
||||
add_cmd ("data", class_vars, NULL, "Examining data.", &cmdlist);
|
||||
add_cmd ("stack", class_stack, NULL, "Examining the stack.\n\
|
||||
The stack is made up of stack frames. Gdb assigns numbers to stack frames\n\
|
||||
counting from zero for the innermost (currently executing) frame.\n\n\
|
||||
At any time gdb identifies one frame as the \"selected\" frame.\n\
|
||||
Variable lookups are done with respect to the selected frame.\n\
|
||||
When the program being debugged stops, gdb selects the innermost frame.\n\
|
||||
The commands below can be used to select other frames by number or address.",
|
||||
&cmdlist);
|
||||
add_cmd ("running", class_run, NULL, "Running the program.", &cmdlist);
|
||||
|
||||
/* Define general commands. */
|
||||
|
||||
add_com ("pwd", class_files, pwd_command,
|
||||
"Print working directory. This is used for your program as well.");
|
||||
c = add_cmd ("cd", class_files, cd_command,
|
||||
"Set working directory to DIR for debugger and program being debugged.\n\
|
||||
The change does not take effect for the program being debugged\n\
|
||||
until the next time it is started.", &cmdlist);
|
||||
c->completer = filename_completer;
|
||||
|
||||
add_com ("echo", class_support, echo_command,
|
||||
"Print a constant string. Give string as argument.\n\
|
||||
C escape sequences may be used in the argument.\n\
|
||||
No newline is added at the end of the argument;\n\
|
||||
use \"\\n\" if you want a newline to be printed.\n\
|
||||
Since leading and trailing whitespace are ignored in command arguments,\n\
|
||||
if you want to print some you must use \"\\\" before leading whitespace\n\
|
||||
to be printed or after trailing whitespace.");
|
||||
add_com ("document", class_support, document_command,
|
||||
"Document a user-defined command.\n\
|
||||
Give command name as argument. Give documentation on following lines.\n\
|
||||
End with a line of just \"end\".");
|
||||
add_com ("define", class_support, define_command,
|
||||
"Define a new command name. Command name is argument.\n\
|
||||
Definition appears on following lines, one command per line.\n\
|
||||
End with a line of just \"end\".\n\
|
||||
Use the \"document\" command to give documentation for the new command.\n\
|
||||
Commands defined in this way may have up to ten arguments.");
|
||||
|
||||
c = add_cmd ("source", class_support, source_command,
|
||||
"Read commands from a file named FILE.\n\
|
||||
Note that the file \"" GDBINIT_FILENAME "\" is read automatically in this way\n\
|
||||
when gdb is started.", &cmdlist);
|
||||
c->completer = filename_completer;
|
||||
|
||||
add_com ("quit", class_support, quit_command, "Exit gdb.");
|
||||
c = add_com ("help", class_support, help_command, "Print list of commands.");
|
||||
c->completer = command_completer;
|
||||
add_com_alias ("q", "quit", class_support, 1);
|
||||
add_com_alias ("h", "help", class_support, 1);
|
||||
|
||||
c = add_set_cmd ("verbose", class_support, var_boolean, (char *) &info_verbose,
|
||||
"Set ",
|
||||
&setlist),
|
||||
add_show_from_set (c, &showlist);
|
||||
set_cmd_sfunc (c, set_verbose);
|
||||
set_verbose (NULL, 0, c);
|
||||
|
||||
add_prefix_cmd ("history", class_support, set_history,
|
||||
"Generic command for setting command history parameters.",
|
||||
&sethistlist, "set history ", 0, &setlist);
|
||||
add_prefix_cmd ("history", class_support, show_history,
|
||||
"Generic command for showing command history parameters.",
|
||||
&showhistlist, "show history ", 0, &showlist);
|
||||
|
||||
add_show_from_set
|
||||
(add_set_cmd ("expansion", no_class, var_boolean, (char *) &history_expansion_p,
|
||||
"Set history expansion on command input.\n\
|
||||
Without an argument, history expansion is enabled.", &sethistlist),
|
||||
&showhistlist);
|
||||
|
||||
add_prefix_cmd ("info", class_info, info_command,
|
||||
"Generic command for showing things about the program being debugged.",
|
||||
&infolist, "info ", 0, &cmdlist);
|
||||
add_com_alias ("i", "info", class_info, 1);
|
||||
|
||||
add_com ("complete", class_obscure, complete_command,
|
||||
"List the completions for the rest of the line as a command.");
|
||||
|
||||
add_prefix_cmd ("show", class_info, show_command,
|
||||
"Generic command for showing things about the debugger.",
|
||||
&showlist, "show ", 0, &cmdlist);
|
||||
/* Another way to get at the same thing. */
|
||||
add_info ("set", show_command, "Show all GDB settings.");
|
||||
|
||||
add_cmd ("commands", no_class, show_commands,
|
||||
"Show the history of commands you typed.\n\
|
||||
You can supply a command number to start with, or a `+' to start after\n\
|
||||
the previous command number shown.",
|
||||
&showlist);
|
||||
|
||||
add_cmd ("version", no_class, show_version,
|
||||
"Show what version of GDB this is.", &showlist);
|
||||
|
||||
add_com ("while", class_support, while_command,
|
||||
"Execute nested commands WHILE the conditional expression is non zero.\n\
|
||||
The conditional expression must follow the word `while' and must in turn be\n\
|
||||
followed by a new line. The nested commands must be entered one per line,\n\
|
||||
and should be terminated by the word `end'.");
|
||||
|
||||
add_com ("if", class_support, if_command,
|
||||
"Execute nested commands once IF the conditional expression is non zero.\n\
|
||||
The conditional expression must follow the word `if' and must in turn be\n\
|
||||
followed by a new line. The nested commands must be entered one per line,\n\
|
||||
and should be terminated by the word 'else' or `end'. If an else clause\n\
|
||||
is used, the same rules apply to its nested commands as to the first ones.");
|
||||
|
||||
/* If target is open when baud changes, it doesn't take effect until the
|
||||
next open (I think, not sure). */
|
||||
add_show_from_set (add_set_cmd ("remotebaud", no_class,
|
||||
var_zinteger, (char *) &baud_rate,
|
||||
"Set baud rate for remote serial I/O.\n\
|
||||
This value is used to set the speed of the serial port when debugging\n\
|
||||
using remote targets.", &setlist),
|
||||
&showlist);
|
||||
|
||||
c = add_set_cmd ("remotedebug", no_class, var_zinteger,
|
||||
(char *) &remote_debug,
|
||||
"Set debugging of remote protocol.\n\
|
||||
When enabled, each packet sent or received with the remote target\n\
|
||||
is displayed.", &setlist);
|
||||
deprecate_cmd (c, "set debug remote");
|
||||
deprecate_cmd (add_show_from_set (c, &showlist), "show debug remote");
|
||||
|
||||
add_show_from_set (add_set_cmd ("remote", no_class, var_zinteger,
|
||||
(char *) &remote_debug,
|
||||
"Set debugging of remote protocol.\n\
|
||||
When enabled, each packet sent or received with the remote target\n\
|
||||
is displayed.", &setdebuglist),
|
||||
&showdebuglist);
|
||||
|
||||
add_show_from_set (
|
||||
add_set_cmd ("remotetimeout", no_class, var_integer, (char *) &remote_timeout,
|
||||
"Set timeout limit to wait for target to respond.\n\
|
||||
This value is used to set the time limit for gdb to wait for a response\n\
|
||||
from the target.", &setlist),
|
||||
&showlist);
|
||||
|
||||
add_prefix_cmd ("debug", no_class, set_debug,
|
||||
"Generic command for setting gdb debugging flags",
|
||||
&setdebuglist, "set debug ", 0, &setlist);
|
||||
|
||||
add_prefix_cmd ("debug", no_class, show_debug,
|
||||
"Generic command for showing gdb debugging flags",
|
||||
&showdebuglist, "show debug ", 0, &showlist);
|
||||
|
||||
c = add_com ("shell", class_support, shell_escape,
|
||||
"Execute the rest of the line as a shell command. \n\
|
||||
With no arguments, run an inferior shell.");
|
||||
c->completer = filename_completer;
|
||||
|
||||
/* NOTE: cagney/2000-03-20: Being able to enter ``(gdb) !ls'' would
|
||||
be a really useful feature. Unfortunately, the below wont do
|
||||
this. Instead it adds support for the form ``(gdb) ! ls''
|
||||
(i.e. the space is required). If the ``!'' command below is
|
||||
added the complains about no ``!'' command would be replaced by
|
||||
complains about how the ``!'' command is broken :-) */
|
||||
if (xdb_commands)
|
||||
add_com_alias ("!", "shell", class_support, 0);
|
||||
|
||||
c = add_com ("make", class_support, make_command,
|
||||
"Run the ``make'' program using the rest of the line as arguments.");
|
||||
c->completer = filename_completer;
|
||||
add_cmd ("user", no_class, show_user,
|
||||
"Show definitions of user defined commands.\n\
|
||||
Argument is the name of the user defined command.\n\
|
||||
With no argument, show definitions of all user defined commands.", &showlist);
|
||||
add_com ("apropos", class_support, apropos_command, "Search for commands matching a REGEXP");
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/* Header file for GDB CLI command implementation library.
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (CLI_CMDS_H)
|
||||
#define CLI_CMDS_H 1
|
||||
|
||||
/* Chain containing all defined commands. */
|
||||
|
||||
extern struct cmd_list_element *cmdlist;
|
||||
|
||||
/* Chain containing all defined info subcommands. */
|
||||
|
||||
extern struct cmd_list_element *infolist;
|
||||
|
||||
/* Chain containing all defined enable subcommands. */
|
||||
|
||||
extern struct cmd_list_element *enablelist;
|
||||
|
||||
/* Chain containing all defined disable subcommands. */
|
||||
|
||||
extern struct cmd_list_element *disablelist;
|
||||
|
||||
/* Chain containing all defined delete subcommands. */
|
||||
|
||||
extern struct cmd_list_element *deletelist;
|
||||
|
||||
/* Chain containing all defined toggle subcommands. */
|
||||
|
||||
extern struct cmd_list_element *togglelist;
|
||||
|
||||
/* Chain containing all defined stop subcommands. */
|
||||
|
||||
extern struct cmd_list_element *stoplist;
|
||||
|
||||
/* Chain containing all defined "enable breakpoint" subcommands. */
|
||||
|
||||
extern struct cmd_list_element *enablebreaklist;
|
||||
|
||||
/* Chain containing all defined set subcommands */
|
||||
|
||||
extern struct cmd_list_element *setlist;
|
||||
|
||||
/* Chain containing all defined unset subcommands */
|
||||
|
||||
extern struct cmd_list_element *unsetlist;
|
||||
|
||||
/* Chain containing all defined show subcommands. */
|
||||
|
||||
extern struct cmd_list_element *showlist;
|
||||
|
||||
/* Chain containing all defined \"set history\". */
|
||||
|
||||
extern struct cmd_list_element *sethistlist;
|
||||
|
||||
/* Chain containing all defined \"show history\". */
|
||||
|
||||
extern struct cmd_list_element *showhistlist;
|
||||
|
||||
/* Chain containing all defined \"unset history\". */
|
||||
|
||||
extern struct cmd_list_element *unsethistlist;
|
||||
|
||||
/* Chain containing all defined maintenance subcommands. */
|
||||
|
||||
extern struct cmd_list_element *maintenancelist;
|
||||
|
||||
/* Chain containing all defined "maintenance info" subcommands. */
|
||||
|
||||
extern struct cmd_list_element *maintenanceinfolist;
|
||||
|
||||
/* Chain containing all defined "maintenance print" subcommands. */
|
||||
|
||||
extern struct cmd_list_element *maintenanceprintlist;
|
||||
|
||||
extern struct cmd_list_element *setprintlist;
|
||||
|
||||
extern struct cmd_list_element *showprintlist;
|
||||
|
||||
extern struct cmd_list_element *setdebuglist;
|
||||
|
||||
extern struct cmd_list_element *showdebuglist;
|
||||
|
||||
extern struct cmd_list_element *setchecklist;
|
||||
|
||||
extern struct cmd_list_element *showchecklist;
|
||||
|
||||
/* Exported to gdb/top.c */
|
||||
|
||||
void init_cmd_lists (void);
|
||||
|
||||
void init_cli_cmds (void);
|
||||
|
||||
int is_complete_command (void (*func) (char *args, int from_tty));
|
||||
|
||||
/* Exported to gdb/main.c */
|
||||
|
||||
extern void cd_command (char *, int);
|
||||
|
||||
/* Exported to gdb/top.c and gdb/main.c */
|
||||
|
||||
extern void quit_command (char *, int);
|
||||
|
||||
extern void source_command (char *, int);
|
||||
|
||||
/* Used everywhere whenever at least one parameter is required and
|
||||
none is specified. */
|
||||
|
||||
extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
|
||||
|
||||
#endif /* !defined (CLI_CMDS_H) */
|
||||
1402
gdb/cli/cli-decode.c
1402
gdb/cli/cli-decode.c
File diff suppressed because it is too large
Load Diff
@@ -1,381 +0,0 @@
|
||||
/* Header file for GDB command decoding library.
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (CLI_DECODE_H)
|
||||
#define CLI_DECODE_H 1
|
||||
|
||||
#include "gdb_regex.h" /* Needed by apropos_cmd. */
|
||||
|
||||
/* Command classes are top-level categories into which commands are broken
|
||||
down for "help" purposes.
|
||||
Notes on classes: class_alias is for alias commands which are not
|
||||
abbreviations of the original command. class-pseudo is for
|
||||
commands which are not really commands nor help topics ("stop"). */
|
||||
|
||||
enum command_class
|
||||
{
|
||||
/* Special args to help_list */
|
||||
class_deprecated, all_classes = -2, all_commands = -1,
|
||||
/* Classes of commands */
|
||||
no_class = -1, class_run = 0, class_vars, class_stack,
|
||||
class_files, class_support, class_info, class_breakpoint, class_trace,
|
||||
class_alias, class_obscure, class_user, class_maintenance,
|
||||
class_pseudo, class_tui, class_xdb
|
||||
};
|
||||
|
||||
/* Not a set/show command. Note that some commands which begin with
|
||||
"set" or "show" might be in this category, if their syntax does
|
||||
not fall into one of the following categories. */
|
||||
typedef enum cmd_types
|
||||
{
|
||||
not_set_cmd,
|
||||
set_cmd,
|
||||
show_cmd
|
||||
}
|
||||
cmd_types;
|
||||
|
||||
/* Reasonable values for an AUTO_BOOLEAN variable. */
|
||||
enum cmd_auto_boolean
|
||||
{
|
||||
CMD_AUTO_BOOLEAN_TRUE,
|
||||
CMD_AUTO_BOOLEAN_FALSE,
|
||||
CMD_AUTO_BOOLEAN_AUTO
|
||||
};
|
||||
|
||||
/* Types of "set" or "show" command. */
|
||||
typedef enum var_types
|
||||
{
|
||||
/* "on" or "off". *VAR is an integer which is nonzero for on,
|
||||
zero for off. */
|
||||
var_boolean,
|
||||
|
||||
/* "on" / "true" / "enable" or "off" / "false" / "disable" or
|
||||
"auto. *VAR is an ``enum cmd_auto_boolean''. NOTE: In general
|
||||
a custom show command will need to be implemented - one that
|
||||
for "auto" prints both the "auto" and the current auto-selected
|
||||
value. */
|
||||
var_auto_boolean,
|
||||
|
||||
/* Unsigned Integer. *VAR is an unsigned int. The user can type 0
|
||||
to mean "unlimited", which is stored in *VAR as UINT_MAX. */
|
||||
var_uinteger,
|
||||
|
||||
/* Like var_uinteger but signed. *VAR is an int. The user can type 0
|
||||
to mean "unlimited", which is stored in *VAR as INT_MAX. */
|
||||
var_integer,
|
||||
|
||||
/* String which the user enters with escapes (e.g. the user types \n and
|
||||
it is a real newline in the stored string).
|
||||
*VAR is a malloc'd string, or NULL if the string is empty. */
|
||||
var_string,
|
||||
/* String which stores what the user types verbatim.
|
||||
*VAR is a malloc'd string, or NULL if the string is empty. */
|
||||
var_string_noescape,
|
||||
/* String which stores a filename.
|
||||
*VAR is a malloc'd string, or NULL if the string is empty. */
|
||||
var_filename,
|
||||
/* ZeroableInteger. *VAR is an int. Like Unsigned Integer except
|
||||
that zero really means zero. */
|
||||
var_zinteger,
|
||||
/* Enumerated type. Can only have one of the specified values. *VAR is a
|
||||
char pointer to the name of the element that we find. */
|
||||
var_enum
|
||||
}
|
||||
var_types;
|
||||
|
||||
/* This structure records one command'd definition. */
|
||||
|
||||
|
||||
/* This flag is used by the code executing commands to warn the user
|
||||
the first time a deprecated command is used, see the 'flags' field in
|
||||
the following struct.
|
||||
*/
|
||||
#define CMD_DEPRECATED 0x1
|
||||
#define DEPRECATED_WARN_USER 0x2
|
||||
#define MALLOCED_REPLACEMENT 0x4
|
||||
|
||||
struct cmd_list_element
|
||||
{
|
||||
/* Points to next command in this list. */
|
||||
struct cmd_list_element *next;
|
||||
|
||||
/* Name of this command. */
|
||||
char *name;
|
||||
|
||||
/* Command class; class values are chosen by application program. */
|
||||
enum command_class class;
|
||||
|
||||
/* Function definition of this command. NULL for command class
|
||||
names and for help topics that are not really commands. NOTE:
|
||||
cagney/2002-02-02: This function signature is evolving. For
|
||||
the moment suggest sticking with either set_cmd_cfunc() or
|
||||
set_cmd_sfunc(). */
|
||||
void (*func) (struct cmd_list_element *c, char *args, int from_tty);
|
||||
/* The command's real callback. At present func() bounces through
|
||||
to one of the below. */
|
||||
union
|
||||
{
|
||||
/* If type is not_set_cmd, call it like this: */
|
||||
void (*cfunc) (char *args, int from_tty);
|
||||
|
||||
/* If type is set_cmd or show_cmd, first set the variables, and
|
||||
then call this. */
|
||||
void (*sfunc) (char *args, int from_tty, struct cmd_list_element * c);
|
||||
}
|
||||
function;
|
||||
|
||||
/* Documentation of this command (or help topic).
|
||||
First line is brief documentation; remaining lines form, with it,
|
||||
the full documentation. First line should end with a period.
|
||||
Entire string should also end with a period, not a newline. */
|
||||
char *doc;
|
||||
|
||||
/* flags : a bitfield
|
||||
|
||||
bit 0: (LSB) CMD_DEPRECATED, when 1 indicated that this command
|
||||
is deprecated. It may be removed from gdb's command set in the
|
||||
future.
|
||||
|
||||
bit 1: DEPRECATED_WARN_USER, the user needs to be warned that
|
||||
this is a deprecated command. The user should only be warned
|
||||
the first time a command is used.
|
||||
|
||||
bit 2: MALLOCED_REPLACEMENT, when functions are deprecated at
|
||||
compile time (this is the way it should, in general, be done)
|
||||
the memory containing the replacement string is statically
|
||||
allocated. In some cases it makes sense to deprecate commands
|
||||
at runtime (the testsuite is one example). In this case the
|
||||
memory for replacement is malloc'ed. When a command is
|
||||
undeprecated or re-deprecated at runtime we don't want to risk
|
||||
calling free on statically allocated memory, so we check this
|
||||
flag.
|
||||
*/
|
||||
int flags;
|
||||
|
||||
/* if this command is deprecated, this is the replacement name */
|
||||
char *replacement;
|
||||
|
||||
/* If this command represents a show command, then this function
|
||||
is called before the variable's value is examined. */
|
||||
void (*pre_show_hook) (struct cmd_list_element *c);
|
||||
|
||||
/* Hook for another command to be executed before this command. */
|
||||
struct cmd_list_element *hook_pre;
|
||||
|
||||
/* Hook for another command to be executed after this command. */
|
||||
struct cmd_list_element *hook_post;
|
||||
|
||||
/* Flag that specifies if this command is already running it's hook. */
|
||||
/* Prevents the possibility of hook recursion. */
|
||||
int hook_in;
|
||||
|
||||
/* Nonzero identifies a prefix command. For them, the address
|
||||
of the variable containing the list of subcommands. */
|
||||
struct cmd_list_element **prefixlist;
|
||||
|
||||
/* For prefix commands only:
|
||||
String containing prefix commands to get here: this one
|
||||
plus any others needed to get to it. Should end in a space.
|
||||
It is used before the word "command" in describing the
|
||||
commands reached through this prefix. */
|
||||
char *prefixname;
|
||||
|
||||
/* For prefix commands only:
|
||||
nonzero means do not get an error if subcommand is not
|
||||
recognized; call the prefix's own function in that case. */
|
||||
char allow_unknown;
|
||||
|
||||
/* Nonzero says this is an abbreviation, and should not
|
||||
be mentioned in lists of commands.
|
||||
This allows "br<tab>" to complete to "break", which it
|
||||
otherwise wouldn't. */
|
||||
char abbrev_flag;
|
||||
|
||||
/* Completion routine for this command. TEXT is the text beyond
|
||||
what was matched for the command itself (leading whitespace is
|
||||
skipped). It stops where we are supposed to stop completing
|
||||
(rl_point) and is '\0' terminated.
|
||||
|
||||
Return value is a malloc'd vector of pointers to possible completions
|
||||
terminated with NULL. If there are no completions, returning a pointer
|
||||
to a NULL would work but returning NULL itself is also valid.
|
||||
WORD points in the same buffer as TEXT, and completions should be
|
||||
returned relative to this position. For example, suppose TEXT is "foo"
|
||||
and we want to complete to "foobar". If WORD is "oo", return
|
||||
"oobar"; if WORD is "baz/foo", return "baz/foobar". */
|
||||
char **(*completer) (char *text, char *word);
|
||||
|
||||
/* Type of "set" or "show" command (or SET_NOT_SET if not "set"
|
||||
or "show"). */
|
||||
cmd_types type;
|
||||
|
||||
/* Pointer to variable affected by "set" and "show". Doesn't matter
|
||||
if type is not_set. */
|
||||
void *var;
|
||||
|
||||
/* What kind of variable is *VAR? */
|
||||
var_types var_type;
|
||||
|
||||
/* Pointer to NULL terminated list of enumerated values (like argv). */
|
||||
const char **enums;
|
||||
|
||||
/* Pointer to command strings of user-defined commands */
|
||||
struct command_line *user_commands;
|
||||
|
||||
/* Pointer to command that is hooked by this one, (by hook_pre)
|
||||
so the hook can be removed when this one is deleted. */
|
||||
struct cmd_list_element *hookee_pre;
|
||||
|
||||
/* Pointer to command that is hooked by this one, (by hook_post)
|
||||
so the hook can be removed when this one is deleted. */
|
||||
struct cmd_list_element *hookee_post;
|
||||
|
||||
/* Pointer to command that is aliased by this one, so the
|
||||
aliased command can be located in case it has been hooked. */
|
||||
struct cmd_list_element *cmd_pointer;
|
||||
};
|
||||
|
||||
/* API to the manipulation of command lists. */
|
||||
|
||||
extern struct cmd_list_element *add_cmd (char *, enum command_class,
|
||||
void (*fun) (char *, int), char *,
|
||||
struct cmd_list_element **);
|
||||
|
||||
extern struct cmd_list_element *add_alias_cmd (char *, char *,
|
||||
enum command_class, int,
|
||||
struct cmd_list_element **);
|
||||
|
||||
extern struct cmd_list_element *add_prefix_cmd (char *, enum command_class,
|
||||
void (*fun) (char *, int),
|
||||
char *,
|
||||
struct cmd_list_element **,
|
||||
char *, int,
|
||||
struct cmd_list_element **);
|
||||
|
||||
extern struct cmd_list_element *add_abbrev_prefix_cmd (char *,
|
||||
enum command_class,
|
||||
void (*fun) (char *,
|
||||
int),
|
||||
char *,
|
||||
struct cmd_list_element
|
||||
**, char *, int,
|
||||
struct cmd_list_element
|
||||
**);
|
||||
|
||||
/* Set the commands corresponding callback. */
|
||||
|
||||
extern void set_cmd_cfunc (struct cmd_list_element *cmd,
|
||||
void (*cfunc) (char *args, int from_tty));
|
||||
|
||||
extern void set_cmd_sfunc (struct cmd_list_element *cmd,
|
||||
void (*sfunc) (char *args, int from_tty,
|
||||
struct cmd_list_element * c));
|
||||
|
||||
|
||||
extern struct cmd_list_element *lookup_cmd (char **,
|
||||
struct cmd_list_element *, char *,
|
||||
int, int);
|
||||
|
||||
extern struct cmd_list_element *lookup_cmd_1 (char **,
|
||||
struct cmd_list_element *,
|
||||
struct cmd_list_element **,
|
||||
int);
|
||||
|
||||
extern struct cmd_list_element *
|
||||
deprecate_cmd (struct cmd_list_element *, char * );
|
||||
|
||||
extern void
|
||||
deprecated_cmd_warning (char **);
|
||||
|
||||
extern int
|
||||
lookup_cmd_composition (char *text,
|
||||
struct cmd_list_element **alias,
|
||||
struct cmd_list_element **prefix_cmd,
|
||||
struct cmd_list_element **cmd);
|
||||
|
||||
extern struct cmd_list_element *add_com (char *, enum command_class,
|
||||
void (*fun) (char *, int), char *);
|
||||
|
||||
extern struct cmd_list_element *add_com_alias (char *, char *,
|
||||
enum command_class, int);
|
||||
|
||||
extern struct cmd_list_element *add_info (char *, void (*fun) (char *, int),
|
||||
char *);
|
||||
|
||||
extern struct cmd_list_element *add_info_alias (char *, char *, int);
|
||||
|
||||
extern char **complete_on_cmdlist (struct cmd_list_element *, char *, char *);
|
||||
|
||||
extern char **complete_on_enum (const char *enumlist[], char *, char *);
|
||||
|
||||
extern void delete_cmd (char *, struct cmd_list_element **);
|
||||
|
||||
extern void help_cmd_list (struct cmd_list_element *, enum command_class,
|
||||
char *, int, struct ui_file *);
|
||||
|
||||
extern struct cmd_list_element *add_set_cmd (char *name, enum
|
||||
command_class class,
|
||||
var_types var_type, void *var,
|
||||
char *doc,
|
||||
struct cmd_list_element **list);
|
||||
|
||||
extern struct cmd_list_element *add_set_enum_cmd (char *name,
|
||||
enum command_class class,
|
||||
const char *enumlist[],
|
||||
const char **var,
|
||||
char *doc,
|
||||
struct cmd_list_element **list);
|
||||
|
||||
extern struct cmd_list_element *add_set_auto_boolean_cmd (char *name,
|
||||
enum command_class class,
|
||||
enum cmd_auto_boolean *var,
|
||||
char *doc,
|
||||
struct cmd_list_element **list);
|
||||
|
||||
extern struct cmd_list_element *add_set_boolean_cmd (char *name,
|
||||
enum command_class class,
|
||||
int *var,
|
||||
char *doc,
|
||||
struct cmd_list_element **list);
|
||||
|
||||
extern struct cmd_list_element *add_show_from_set (struct cmd_list_element *,
|
||||
struct cmd_list_element
|
||||
**);
|
||||
|
||||
/* Functions that implement commands about CLI commands. */
|
||||
|
||||
extern void help_cmd (char *, struct ui_file *);
|
||||
|
||||
extern void help_list (struct cmd_list_element *, char *,
|
||||
enum command_class, struct ui_file *);
|
||||
|
||||
extern void apropos_cmd (struct ui_file *, struct cmd_list_element *,
|
||||
struct re_pattern_buffer *, char *);
|
||||
|
||||
/* Used to mark commands that don't do anything. If we just leave the
|
||||
function field NULL, the command is interpreted as a help topic, or
|
||||
as a class of commands. */
|
||||
|
||||
extern void not_just_help_class_command (char *arg, int from_tty);
|
||||
|
||||
/* Exported to cli/cli-setshow.c */
|
||||
|
||||
extern void print_doc_line (struct ui_file *, char *);
|
||||
|
||||
|
||||
#endif /* !defined (CLI_DECODE_H) */
|
||||
1228
gdb/cli/cli-script.c
1228
gdb/cli/cli-script.c
File diff suppressed because it is too large
Load Diff
@@ -1,48 +0,0 @@
|
||||
/* Header file for GDB CLI command implementation library.
|
||||
Copyright 2000, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (CLI_SCRIPT_H)
|
||||
#define CLI_SCRIPT_H 1
|
||||
|
||||
/* Exported to cli/cli-cmds.c */
|
||||
|
||||
extern void script_from_file (FILE *stream, char *file);
|
||||
|
||||
extern void document_command (char *, int);
|
||||
|
||||
extern void define_command (char *, int);
|
||||
|
||||
extern void while_command (char *arg, int from_tty);
|
||||
|
||||
extern void if_command (char *arg, int from_tty);
|
||||
|
||||
extern void show_user_1 (struct cmd_list_element *c, struct ui_file *stream);
|
||||
|
||||
/* Exported to gdb/breakpoint.c */
|
||||
|
||||
extern enum command_control_type
|
||||
execute_control_command (struct command_line *cmd);
|
||||
|
||||
extern void print_command_lines (struct ui_out *,
|
||||
struct command_line *, unsigned int);
|
||||
|
||||
/* Exported to gdb/infrun.c */
|
||||
|
||||
extern void execute_user_command (struct cmd_list_element *c, char *args);
|
||||
|
||||
#endif /* !defined (CLI_SCRIPT_H) */
|
||||
@@ -1,382 +0,0 @@
|
||||
/* Handle set and show GDB commands.
|
||||
|
||||
Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "value.h"
|
||||
#include <ctype.h>
|
||||
#if 0
|
||||
#include "gdb_string.h"
|
||||
#endif
|
||||
|
||||
#include "ui-out.h"
|
||||
|
||||
#include "cli/cli-decode.h"
|
||||
#include "cli/cli-cmds.h"
|
||||
#include "cli/cli-setshow.h"
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
static int parse_binary_operation (char *);
|
||||
|
||||
static enum cmd_auto_boolean parse_auto_binary_operation (const char *arg);
|
||||
|
||||
static enum cmd_auto_boolean
|
||||
parse_auto_binary_operation (const char *arg)
|
||||
{
|
||||
if (arg != NULL && *arg != '\0')
|
||||
{
|
||||
int length = strlen (arg);
|
||||
while (isspace (arg[length - 1]) && length > 0)
|
||||
length--;
|
||||
if (strncmp (arg, "on", length) == 0
|
||||
|| strncmp (arg, "1", length) == 0
|
||||
|| strncmp (arg, "yes", length) == 0
|
||||
|| strncmp (arg, "enable", length) == 0)
|
||||
return CMD_AUTO_BOOLEAN_TRUE;
|
||||
else if (strncmp (arg, "off", length) == 0
|
||||
|| strncmp (arg, "0", length) == 0
|
||||
|| strncmp (arg, "no", length) == 0
|
||||
|| strncmp (arg, "disable", length) == 0)
|
||||
return CMD_AUTO_BOOLEAN_FALSE;
|
||||
else if (strncmp (arg, "auto", length) == 0
|
||||
|| (strncmp (arg, "-1", length) == 0 && length > 1))
|
||||
return CMD_AUTO_BOOLEAN_AUTO;
|
||||
}
|
||||
error ("\"on\", \"off\" or \"auto\" expected.");
|
||||
return CMD_AUTO_BOOLEAN_AUTO; /* pacify GCC */
|
||||
}
|
||||
|
||||
static int
|
||||
parse_binary_operation (char *arg)
|
||||
{
|
||||
int length;
|
||||
|
||||
if (!arg || !*arg)
|
||||
return 1;
|
||||
|
||||
length = strlen (arg);
|
||||
|
||||
while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
|
||||
length--;
|
||||
|
||||
if (strncmp (arg, "on", length) == 0
|
||||
|| strncmp (arg, "1", length) == 0
|
||||
|| strncmp (arg, "yes", length) == 0
|
||||
|| strncmp (arg, "enable", length) == 0)
|
||||
return 1;
|
||||
else if (strncmp (arg, "off", length) == 0
|
||||
|| strncmp (arg, "0", length) == 0
|
||||
|| strncmp (arg, "no", length) == 0
|
||||
|| strncmp (arg, "disable", length) == 0)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
error ("\"on\" or \"off\" expected.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do a "set" or "show" command. ARG is NULL if no argument, or the text
|
||||
of the argument, and FROM_TTY is nonzero if this command is being entered
|
||||
directly by the user (i.e. these are just like any other
|
||||
command). C is the command list element for the command. */
|
||||
|
||||
void
|
||||
do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
if (c->type == set_cmd)
|
||||
{
|
||||
switch (c->var_type)
|
||||
{
|
||||
case var_string:
|
||||
{
|
||||
char *new;
|
||||
char *p;
|
||||
char *q;
|
||||
int ch;
|
||||
|
||||
if (arg == NULL)
|
||||
arg = "";
|
||||
new = (char *) xmalloc (strlen (arg) + 2);
|
||||
p = arg;
|
||||
q = new;
|
||||
while ((ch = *p++) != '\000')
|
||||
{
|
||||
if (ch == '\\')
|
||||
{
|
||||
/* \ at end of argument is used after spaces
|
||||
so they won't be lost. */
|
||||
/* This is obsolete now that we no longer strip
|
||||
trailing whitespace and actually, the backslash
|
||||
didn't get here in my test, readline or
|
||||
something did something funky with a backslash
|
||||
right before a newline. */
|
||||
if (*p == 0)
|
||||
break;
|
||||
ch = parse_escape (&p);
|
||||
if (ch == 0)
|
||||
break; /* C loses */
|
||||
else if (ch > 0)
|
||||
*q++ = ch;
|
||||
}
|
||||
else
|
||||
*q++ = ch;
|
||||
}
|
||||
#if 0
|
||||
if (*(p - 1) != '\\')
|
||||
*q++ = ' ';
|
||||
#endif
|
||||
*q++ = '\0';
|
||||
new = (char *) xrealloc (new, q - new);
|
||||
if (*(char **) c->var != NULL)
|
||||
xfree (*(char **) c->var);
|
||||
*(char **) c->var = new;
|
||||
}
|
||||
break;
|
||||
case var_string_noescape:
|
||||
if (arg == NULL)
|
||||
arg = "";
|
||||
if (*(char **) c->var != NULL)
|
||||
xfree (*(char **) c->var);
|
||||
*(char **) c->var = savestring (arg, strlen (arg));
|
||||
break;
|
||||
case var_filename:
|
||||
if (arg == NULL)
|
||||
error_no_arg ("filename to set it to.");
|
||||
if (*(char **) c->var != NULL)
|
||||
xfree (*(char **) c->var);
|
||||
*(char **) c->var = tilde_expand (arg);
|
||||
break;
|
||||
case var_boolean:
|
||||
*(int *) c->var = parse_binary_operation (arg);
|
||||
break;
|
||||
case var_auto_boolean:
|
||||
*(enum cmd_auto_boolean *) c->var = parse_auto_binary_operation (arg);
|
||||
break;
|
||||
case var_uinteger:
|
||||
if (arg == NULL)
|
||||
error_no_arg ("integer to set it to.");
|
||||
*(unsigned int *) c->var = parse_and_eval_long (arg);
|
||||
if (*(unsigned int *) c->var == 0)
|
||||
*(unsigned int *) c->var = UINT_MAX;
|
||||
break;
|
||||
case var_integer:
|
||||
{
|
||||
unsigned int val;
|
||||
if (arg == NULL)
|
||||
error_no_arg ("integer to set it to.");
|
||||
val = parse_and_eval_long (arg);
|
||||
if (val == 0)
|
||||
*(int *) c->var = INT_MAX;
|
||||
else if (val >= INT_MAX)
|
||||
error ("integer %u out of range", val);
|
||||
else
|
||||
*(int *) c->var = val;
|
||||
break;
|
||||
}
|
||||
case var_zinteger:
|
||||
if (arg == NULL)
|
||||
error_no_arg ("integer to set it to.");
|
||||
*(int *) c->var = parse_and_eval_long (arg);
|
||||
break;
|
||||
case var_enum:
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
int nmatches;
|
||||
const char *match = NULL;
|
||||
char *p;
|
||||
|
||||
/* if no argument was supplied, print an informative error message */
|
||||
if (arg == NULL)
|
||||
{
|
||||
char msg[1024];
|
||||
strcpy (msg, "Requires an argument. Valid arguments are ");
|
||||
for (i = 0; c->enums[i]; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
strcat (msg, ", ");
|
||||
strcat (msg, c->enums[i]);
|
||||
}
|
||||
strcat (msg, ".");
|
||||
error (msg);
|
||||
}
|
||||
|
||||
p = strchr (arg, ' ');
|
||||
|
||||
if (p)
|
||||
len = p - arg;
|
||||
else
|
||||
len = strlen (arg);
|
||||
|
||||
nmatches = 0;
|
||||
for (i = 0; c->enums[i]; i++)
|
||||
if (strncmp (arg, c->enums[i], len) == 0)
|
||||
{
|
||||
if (c->enums[i][len] == '\0')
|
||||
{
|
||||
match = c->enums[i];
|
||||
nmatches = 1;
|
||||
break; /* exact match. */
|
||||
}
|
||||
else
|
||||
{
|
||||
match = c->enums[i];
|
||||
nmatches++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nmatches <= 0)
|
||||
error ("Undefined item: \"%s\".", arg);
|
||||
|
||||
if (nmatches > 1)
|
||||
error ("Ambiguous item \"%s\".", arg);
|
||||
|
||||
*(const char **) c->var = match;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error ("gdb internal error: bad var_type in do_setshow_command");
|
||||
}
|
||||
}
|
||||
else if (c->type == show_cmd)
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct ui_stream *stb;
|
||||
int quote;
|
||||
|
||||
stb = ui_out_stream_new (uiout);
|
||||
old_chain = make_cleanup_ui_out_stream_delete (stb);
|
||||
|
||||
/* Possibly call the pre hook. */
|
||||
if (c->pre_show_hook)
|
||||
(c->pre_show_hook) (c);
|
||||
|
||||
/* Print doc minus "show" at start. */
|
||||
print_doc_line (gdb_stdout, c->doc + 5);
|
||||
|
||||
ui_out_text (uiout, " is ");
|
||||
ui_out_wrap_hint (uiout, " ");
|
||||
quote = 0;
|
||||
switch (c->var_type)
|
||||
{
|
||||
case var_string:
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
if (*(unsigned char **) c->var)
|
||||
fputstr_filtered (*(unsigned char **) c->var, '"', stb->stream);
|
||||
quote = 1;
|
||||
}
|
||||
break;
|
||||
case var_string_noescape:
|
||||
case var_filename:
|
||||
case var_enum:
|
||||
if (*(char **) c->var)
|
||||
fputs_filtered (*(char **) c->var, stb->stream);
|
||||
quote = 1;
|
||||
break;
|
||||
case var_boolean:
|
||||
fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
|
||||
break;
|
||||
case var_auto_boolean:
|
||||
switch (*(enum cmd_auto_boolean*) c->var)
|
||||
{
|
||||
case CMD_AUTO_BOOLEAN_TRUE:
|
||||
fputs_filtered ("on", stb->stream);
|
||||
break;
|
||||
case CMD_AUTO_BOOLEAN_FALSE:
|
||||
fputs_filtered ("off", stb->stream);
|
||||
break;
|
||||
case CMD_AUTO_BOOLEAN_AUTO:
|
||||
fputs_filtered ("auto", stb->stream);
|
||||
break;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"do_setshow_command: invalid var_auto_boolean");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case var_uinteger:
|
||||
if (*(unsigned int *) c->var == UINT_MAX)
|
||||
{
|
||||
fputs_filtered ("unlimited", stb->stream);
|
||||
break;
|
||||
}
|
||||
/* else fall through */
|
||||
case var_zinteger:
|
||||
fprintf_filtered (stb->stream, "%u", *(unsigned int *) c->var);
|
||||
break;
|
||||
case var_integer:
|
||||
if (*(int *) c->var == INT_MAX)
|
||||
{
|
||||
fputs_filtered ("unlimited", stb->stream);
|
||||
}
|
||||
else
|
||||
fprintf_filtered (stb->stream, "%d", *(int *) c->var);
|
||||
break;
|
||||
|
||||
default:
|
||||
error ("gdb internal error: bad var_type in do_setshow_command");
|
||||
}
|
||||
if (quote)
|
||||
ui_out_text (uiout, "\"");
|
||||
ui_out_field_stream (uiout, "value", stb);
|
||||
if (quote)
|
||||
ui_out_text (uiout, "\"");
|
||||
ui_out_text (uiout, ".\n");
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
else
|
||||
error ("gdb internal error: bad cmd_type in do_setshow_command");
|
||||
c->func (c, NULL, from_tty);
|
||||
if (c->type == set_cmd && set_hook)
|
||||
set_hook (c);
|
||||
}
|
||||
|
||||
/* Show all the settings in a list of show commands. */
|
||||
|
||||
void
|
||||
cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
|
||||
{
|
||||
ui_out_tuple_begin (uiout, "showlist");
|
||||
for (; list != NULL; list = list->next)
|
||||
{
|
||||
/* If we find a prefix, run its list, prefixing our output by its
|
||||
prefix (with "show " skipped). */
|
||||
if (list->prefixlist && !list->abbrev_flag)
|
||||
{
|
||||
ui_out_tuple_begin (uiout, "optionlist");
|
||||
ui_out_field_string (uiout, "prefix", list->prefixname + 5);
|
||||
cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
|
||||
ui_out_tuple_end (uiout);
|
||||
}
|
||||
if (list->type == show_cmd)
|
||||
{
|
||||
ui_out_tuple_begin (uiout, "option");
|
||||
ui_out_text (uiout, prefix);
|
||||
ui_out_field_string (uiout, "name", list->name);
|
||||
ui_out_text (uiout, ": ");
|
||||
do_setshow_command ((char *) NULL, from_tty, list);
|
||||
ui_out_tuple_end (uiout);
|
||||
}
|
||||
}
|
||||
ui_out_tuple_end (uiout);
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/* Header file for GDB CLI set and show commands implementation.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (CLI_SETSHOW_H)
|
||||
#define CLI_SETSHOW_H 1
|
||||
|
||||
/* Exported to cli/cli-cmds.c and gdb/top.c */
|
||||
|
||||
/* Do a "set" or "show" command. ARG is NULL if no argument, or the text
|
||||
of the argument, and FROM_TTY is nonzero if this command is being entered
|
||||
directly by the user (i.e. these are just like any other
|
||||
command). C is the command list element for the command. */
|
||||
extern void do_setshow_command (char *arg, int from_tty,
|
||||
struct cmd_list_element *c);
|
||||
|
||||
/* Exported to cli/cli-cmds.c and gdb/top.c, language.c and valprint.c */
|
||||
|
||||
extern void cmd_show_list (struct cmd_list_element *list, int from_tty,
|
||||
char *prefix);
|
||||
|
||||
#endif /* !defined (CLI_SETSHOW_H) */
|
||||
@@ -1,21 +0,0 @@
|
||||
/* GDB CLI utility library.
|
||||
Copyright 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "cli/cli-utils.h"
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/* Header file for GDB CLI utility library.
|
||||
Copyright 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (CLI_UTILS_H)
|
||||
# define CLI_UTILS_H 1
|
||||
|
||||
#endif /* !defined (CLI_UTILS_H) */
|
||||
134
gdb/coff-solib.c
134
gdb/coff-solib.c
@@ -1,134 +0,0 @@
|
||||
/* Handle COFF SVR3 shared libraries for GDB, the GNU Debugger.
|
||||
Copyright 1993, 1994, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#include "frame.h"
|
||||
#include "bfd.h"
|
||||
#include "gdbcore.h"
|
||||
#include "symtab.h"
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
|
||||
/*
|
||||
|
||||
GLOBAL FUNCTION
|
||||
|
||||
coff_solib_add -- add a shared library files to the symtab list. We
|
||||
examine the `.lib' section of the exec file and determine the names of
|
||||
the shared libraries.
|
||||
|
||||
This function is responsible for discovering those names and
|
||||
addresses, and saving sufficient information about them to allow
|
||||
their symbols to be read at a later time.
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
void coff_solib_add (char *arg_string, int from_tty,
|
||||
struct target_ops *target, int readsyms)
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
*/
|
||||
|
||||
void
|
||||
coff_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
|
||||
{
|
||||
asection *libsect;
|
||||
|
||||
if (!readsyms)
|
||||
return;
|
||||
|
||||
libsect = bfd_get_section_by_name (exec_bfd, ".lib");
|
||||
|
||||
if (libsect)
|
||||
{
|
||||
int libsize;
|
||||
unsigned char *lib;
|
||||
struct libent
|
||||
{
|
||||
bfd_byte len[4];
|
||||
bfd_byte nameoffset[4];
|
||||
};
|
||||
|
||||
libsize = bfd_section_size (exec_bfd, libsect);
|
||||
|
||||
lib = (unsigned char *) alloca (libsize);
|
||||
|
||||
bfd_get_section_contents (exec_bfd, libsect, lib, 0, libsize);
|
||||
|
||||
while (libsize > 0)
|
||||
{
|
||||
struct libent *ent;
|
||||
struct objfile *objfile;
|
||||
int len, nameoffset;
|
||||
char *filename;
|
||||
|
||||
ent = (struct libent *) lib;
|
||||
|
||||
len = bfd_get_32 (exec_bfd, ent->len);
|
||||
|
||||
nameoffset = bfd_get_32 (exec_bfd, ent->nameoffset);
|
||||
|
||||
if (len <= 0)
|
||||
break;
|
||||
|
||||
filename = (char *) ent + nameoffset * 4;
|
||||
|
||||
objfile = symbol_file_add (filename, from_tty,
|
||||
NULL, /* no offsets */
|
||||
0, /* not mainline */
|
||||
OBJF_SHARED); /* flags */
|
||||
|
||||
libsize -= len * 4;
|
||||
lib += len * 4;
|
||||
}
|
||||
|
||||
/* Getting new symbols may change our opinion about what is
|
||||
frameless. */
|
||||
reinit_frame_cache ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
GLOBAL FUNCTION
|
||||
|
||||
coff_solib_create_inferior_hook -- shared library startup support
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
void coff_solib_create_inferior_hook()
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
When gdb starts up the inferior, the kernel maps in the shared
|
||||
libraries. We get here with the target stopped at it's first
|
||||
instruction, and the libraries already mapped. At this point, this
|
||||
function gets called via expansion of the macro
|
||||
SOLIB_CREATE_INFERIOR_HOOK.
|
||||
*/
|
||||
|
||||
void
|
||||
coff_solib_create_inferior_hook (void)
|
||||
{
|
||||
coff_solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
|
||||
}
|
||||
186
gdb/coff-solib.h
186
gdb/coff-solib.h
@@ -1,186 +0,0 @@
|
||||
/* COFF (SVR3) Shared library declarations for GDB, the GNU Debugger.
|
||||
Copyright 1992, 1993, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Forward decl's for prototypes */
|
||||
struct target_ops;
|
||||
|
||||
/* Called when we free all symtabs, to free the shared library information
|
||||
as well. */
|
||||
|
||||
#if 0
|
||||
#define CLEAR_SOLIB coff_clear_solib
|
||||
|
||||
extern void coff_clear_solib (void);
|
||||
#endif
|
||||
|
||||
/* Called to add symbols from a shared library to gdb's symbol table. */
|
||||
|
||||
#define SOLIB_ADD(filename, from_tty, targ, readsyms) \
|
||||
coff_solib_add (filename, from_tty, targ, readsyms)
|
||||
|
||||
extern void coff_solib_add (char *, int, struct target_ops *, int);
|
||||
|
||||
/* Function to be called when the inferior starts up, to discover the names
|
||||
of shared libraries that are dynamically linked, the base addresses to
|
||||
which they are linked, and sufficient information to read in their symbols
|
||||
at a later time. */
|
||||
|
||||
#define SOLIB_CREATE_INFERIOR_HOOK(PID) coff_solib_create_inferior_hook()
|
||||
|
||||
extern void coff_solib_create_inferior_hook (void); /* solib.c */
|
||||
|
||||
/* Function to be called to remove the connection between debugger and
|
||||
dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK.
|
||||
(This operation does not remove shared library information from
|
||||
the debugger, as CLEAR_SOLIB does.)
|
||||
|
||||
This functionality is presently not implemented for this target.
|
||||
*/
|
||||
#define SOLIB_REMOVE_INFERIOR_HOOK(PID) (0)
|
||||
|
||||
/* This function is called by the "catch load" command. It allows
|
||||
the debugger to be notified by the dynamic linker when a specified
|
||||
library file (or any library file, if filename is NULL) is loaded.
|
||||
|
||||
Presently, this functionality is not implemented.
|
||||
*/
|
||||
#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \
|
||||
error("catch of library loads/unloads not yet implemented on this platform")
|
||||
|
||||
/* This function is called by the "catch unload" command. It allows
|
||||
the debugger to be notified by the dynamic linker when a specified
|
||||
library file (or any library file, if filename is NULL) is unloaded.
|
||||
|
||||
Presently, this functionality is not implemented.
|
||||
*/
|
||||
#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename,cond_string) \
|
||||
error("catch of library loads/unloads not yet implemented on this platform")
|
||||
|
||||
/* This function returns TRUE if the dynamic linker has just reported
|
||||
a load of a library.
|
||||
|
||||
This function must be used only when the inferior has stopped in
|
||||
the dynamic linker hook, or undefined results are guaranteed.
|
||||
|
||||
Presently, this functionality is not implemented.
|
||||
*/
|
||||
/*
|
||||
#define SOLIB_HAVE_LOAD_EVENT(pid) \
|
||||
error("catch of library loads/unloads not yet implemented on this platform")
|
||||
*/
|
||||
|
||||
#define SOLIB_HAVE_LOAD_EVENT(pid) \
|
||||
(0)
|
||||
|
||||
/* This function returns a pointer to the string representation of the
|
||||
pathname of the dynamically-linked library that has just been loaded.
|
||||
|
||||
This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
|
||||
or undefined results are guaranteed.
|
||||
|
||||
This string's contents are only valid immediately after the inferior
|
||||
has stopped in the dynamic linker hook, and becomes invalid as soon
|
||||
as the inferior is continued. Clients should make a copy of this
|
||||
string if they wish to continue the inferior and then access the string.
|
||||
|
||||
Presently, this functionality is not implemented.
|
||||
*/
|
||||
|
||||
/*
|
||||
#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
|
||||
error("catch of library loads/unloads not yet implemented on this platform")
|
||||
*/
|
||||
|
||||
#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \
|
||||
(0)
|
||||
|
||||
/* This function returns TRUE if the dynamic linker has just reported
|
||||
an unload of a library.
|
||||
|
||||
This function must be used only when the inferior has stopped in
|
||||
the dynamic linker hook, or undefined results are guaranteed.
|
||||
|
||||
Presently, this functionality is not implemented.
|
||||
*/
|
||||
/*
|
||||
#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
|
||||
error("catch of library loads/unloads not yet implemented on this platform")
|
||||
*/
|
||||
|
||||
#define SOLIB_HAVE_UNLOAD_EVENT(pid) \
|
||||
(0)
|
||||
|
||||
/* This function returns a pointer to the string representation of the
|
||||
pathname of the dynamically-linked library that has just been unloaded.
|
||||
|
||||
This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE,
|
||||
or undefined results are guaranteed.
|
||||
|
||||
This string's contents are only valid immediately after the inferior
|
||||
has stopped in the dynamic linker hook, and becomes invalid as soon
|
||||
as the inferior is continued. Clients should make a copy of this
|
||||
string if they wish to continue the inferior and then access the string.
|
||||
|
||||
Presently, this functionality is not implemented.
|
||||
*/
|
||||
/*
|
||||
#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
|
||||
error("catch of library loads/unloads not yet implemented on this platform")
|
||||
*/
|
||||
|
||||
#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \
|
||||
(0)
|
||||
|
||||
/* This function returns TRUE if pc is the address of an instruction that
|
||||
lies within the dynamic linker (such as the event hook, or the dld
|
||||
itself).
|
||||
|
||||
This function must be used only when a dynamic linker event has been
|
||||
caught, and the inferior is being stepped out of the hook, or undefined
|
||||
results are guaranteed.
|
||||
|
||||
Presently, this functionality is not implemented.
|
||||
*/
|
||||
|
||||
/*
|
||||
#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
|
||||
error("catch of library loads/unloads not yet implemented on this platform")
|
||||
*/
|
||||
|
||||
#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \
|
||||
(0)
|
||||
|
||||
/* This function must be called when the inferior is killed, and the program
|
||||
restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard
|
||||
any symbol tables.
|
||||
|
||||
Presently, this functionality is not implemented.
|
||||
*/
|
||||
#define SOLIB_RESTART() \
|
||||
(0)
|
||||
|
||||
/* If we can't set a breakpoint, and it's in a shared library, just
|
||||
disable it. */
|
||||
|
||||
#if 0
|
||||
#define DISABLE_UNSETTABLE_BREAK(addr) coff_solib_address(addr)
|
||||
|
||||
extern int solib_address (CORE_ADDR); /* solib.c */
|
||||
#endif
|
||||
2178
gdb/coffread.c
2178
gdb/coffread.c
File diff suppressed because it is too large
Load Diff
385
gdb/command.h
385
gdb/command.h
@@ -1,385 +0,0 @@
|
||||
/* ***DEPRECATED*** The gdblib files must not be calling/using things in any
|
||||
of the possible command languages. If necessary, a hook (that may be
|
||||
present or not) must be used and set to the appropriate routine by any
|
||||
command language that cares about it. If you are having to include this
|
||||
file you are possibly doing things the old way. This file will disapear.
|
||||
2000-12-01 fnasser@redhat.com */
|
||||
|
||||
/* Header file for command-reading library command.c.
|
||||
Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (COMMAND_H)
|
||||
#define COMMAND_H 1
|
||||
|
||||
/* Command classes are top-level categories into which commands are broken
|
||||
down for "help" purposes.
|
||||
Notes on classes: class_alias is for alias commands which are not
|
||||
abbreviations of the original command. class-pseudo is for
|
||||
commands which are not really commands nor help topics ("stop"). */
|
||||
|
||||
enum command_class
|
||||
{
|
||||
/* Special args to help_list */
|
||||
class_deprecated, all_classes = -2, all_commands = -1,
|
||||
/* Classes of commands */
|
||||
no_class = -1, class_run = 0, class_vars, class_stack,
|
||||
class_files, class_support, class_info, class_breakpoint, class_trace,
|
||||
class_alias, class_obscure, class_user, class_maintenance,
|
||||
class_pseudo, class_tui, class_xdb
|
||||
};
|
||||
|
||||
/* Not a set/show command. Note that some commands which begin with
|
||||
"set" or "show" might be in this category, if their syntax does
|
||||
not fall into one of the following categories. */
|
||||
typedef enum cmd_types
|
||||
{
|
||||
not_set_cmd,
|
||||
set_cmd,
|
||||
show_cmd
|
||||
}
|
||||
cmd_types;
|
||||
|
||||
/* Reasonable values for an AUTO_BOOLEAN variable. */
|
||||
enum cmd_auto_boolean
|
||||
{
|
||||
CMD_AUTO_BOOLEAN_TRUE,
|
||||
CMD_AUTO_BOOLEAN_FALSE,
|
||||
CMD_AUTO_BOOLEAN_AUTO
|
||||
};
|
||||
|
||||
/* Types of "set" or "show" command. */
|
||||
typedef enum var_types
|
||||
{
|
||||
/* "on" or "off". *VAR is an integer which is nonzero for on,
|
||||
zero for off. */
|
||||
var_boolean,
|
||||
|
||||
/* "on" / "true" / "enable" or "off" / "false" / "disable" or
|
||||
"auto. *VAR is an ``enum cmd_auto_boolean''. NOTE: In general
|
||||
a custom show command will need to be implemented - one that
|
||||
for "auto" prints both the "auto" and the current auto-selected
|
||||
value. */
|
||||
var_auto_boolean,
|
||||
|
||||
/* Unsigned Integer. *VAR is an unsigned int. The user can type 0
|
||||
to mean "unlimited", which is stored in *VAR as UINT_MAX. */
|
||||
var_uinteger,
|
||||
|
||||
/* Like var_uinteger but signed. *VAR is an int. The user can type 0
|
||||
to mean "unlimited", which is stored in *VAR as INT_MAX. */
|
||||
var_integer,
|
||||
|
||||
/* String which the user enters with escapes (e.g. the user types \n and
|
||||
it is a real newline in the stored string).
|
||||
*VAR is a malloc'd string, or NULL if the string is empty. */
|
||||
var_string,
|
||||
/* String which stores what the user types verbatim.
|
||||
*VAR is a malloc'd string, or NULL if the string is empty. */
|
||||
var_string_noescape,
|
||||
/* String which stores a filename.
|
||||
*VAR is a malloc'd string, or NULL if the string is empty. */
|
||||
var_filename,
|
||||
/* ZeroableInteger. *VAR is an int. Like Unsigned Integer except
|
||||
that zero really means zero. */
|
||||
var_zinteger,
|
||||
/* Enumerated type. Can only have one of the specified values. *VAR is a
|
||||
char pointer to the name of the element that we find. */
|
||||
var_enum
|
||||
}
|
||||
var_types;
|
||||
|
||||
/* This structure records one command'd definition. */
|
||||
|
||||
|
||||
/* This flag is used by the code executing commands to warn the user
|
||||
the first time a deprecated command is used, see the 'flags' field in
|
||||
the following struct.
|
||||
*/
|
||||
#define CMD_DEPRECATED 0x1
|
||||
#define DEPRECATED_WARN_USER 0x2
|
||||
#define MALLOCED_REPLACEMENT 0x4
|
||||
|
||||
struct cmd_list_element
|
||||
{
|
||||
/* Points to next command in this list. */
|
||||
struct cmd_list_element *next;
|
||||
|
||||
/* Name of this command. */
|
||||
char *name;
|
||||
|
||||
/* Command class; class values are chosen by application program. */
|
||||
enum command_class class;
|
||||
|
||||
/* Function definition of this command. NULL for command class
|
||||
names and for help topics that are not really commands. NOTE:
|
||||
cagney/2002-02-02: This function signature is evolving. For
|
||||
the moment suggest sticking with either set_cmd_cfunc() or
|
||||
set_cmd_sfunc(). */
|
||||
void (*func) (struct cmd_list_element *c, char *args, int from_tty);
|
||||
/* The command's real callback. At present func() bounces through
|
||||
to one of the below. */
|
||||
union
|
||||
{
|
||||
/* If type is not_set_cmd, call it like this: */
|
||||
void (*cfunc) (char *args, int from_tty);
|
||||
|
||||
/* If type is set_cmd or show_cmd, first set the variables, and
|
||||
then call this. */
|
||||
void (*sfunc) (char *args, int from_tty, struct cmd_list_element * c);
|
||||
}
|
||||
function;
|
||||
|
||||
/* Documentation of this command (or help topic).
|
||||
First line is brief documentation; remaining lines form, with it,
|
||||
the full documentation. First line should end with a period.
|
||||
Entire string should also end with a period, not a newline. */
|
||||
char *doc;
|
||||
|
||||
/* flags : a bitfield
|
||||
|
||||
bit 0: (LSB) CMD_DEPRECATED, when 1 indicated that this command
|
||||
is deprecated. It may be removed from gdb's command set in the
|
||||
future.
|
||||
|
||||
bit 1: DEPRECATED_WARN_USER, the user needs to be warned that
|
||||
this is a deprecated command. The user should only be warned
|
||||
the first time a command is used.
|
||||
|
||||
bit 2: MALLOCED_REPLACEMENT, when functions are deprecated at
|
||||
compile time (this is the way it should, in general, be done)
|
||||
the memory containing the replacement string is statically
|
||||
allocated. In some cases it makes sense to deprecate commands
|
||||
at runtime (the testsuite is one example). In this case the
|
||||
memory for replacement is malloc'ed. When a command is
|
||||
undeprecated or re-deprecated at runtime we don't want to risk
|
||||
calling free on statically allocated memory, so we check this
|
||||
flag.
|
||||
*/
|
||||
int flags;
|
||||
|
||||
/* if this command is deprecated, this is the replacement name */
|
||||
char *replacement;
|
||||
|
||||
/* If this command represents a show command, then this function
|
||||
is called before the variable's value is examined. */
|
||||
void (*pre_show_hook) (struct cmd_list_element *c);
|
||||
|
||||
/* Hook for another command to be executed before this command. */
|
||||
struct cmd_list_element *hook_pre;
|
||||
|
||||
/* Hook for another command to be executed after this command. */
|
||||
struct cmd_list_element *hook_post;
|
||||
|
||||
/* Flag that specifies if this command is already running it's hook. */
|
||||
/* Prevents the possibility of hook recursion. */
|
||||
int hook_in;
|
||||
|
||||
/* Nonzero identifies a prefix command. For them, the address
|
||||
of the variable containing the list of subcommands. */
|
||||
struct cmd_list_element **prefixlist;
|
||||
|
||||
/* For prefix commands only:
|
||||
String containing prefix commands to get here: this one
|
||||
plus any others needed to get to it. Should end in a space.
|
||||
It is used before the word "command" in describing the
|
||||
commands reached through this prefix. */
|
||||
char *prefixname;
|
||||
|
||||
/* For prefix commands only:
|
||||
nonzero means do not get an error if subcommand is not
|
||||
recognized; call the prefix's own function in that case. */
|
||||
char allow_unknown;
|
||||
|
||||
/* Nonzero says this is an abbreviation, and should not
|
||||
be mentioned in lists of commands.
|
||||
This allows "br<tab>" to complete to "break", which it
|
||||
otherwise wouldn't. */
|
||||
char abbrev_flag;
|
||||
|
||||
/* Completion routine for this command. TEXT is the text beyond
|
||||
what was matched for the command itself (leading whitespace is
|
||||
skipped). It stops where we are supposed to stop completing
|
||||
(rl_point) and is '\0' terminated.
|
||||
|
||||
Return value is a malloc'd vector of pointers to possible completions
|
||||
terminated with NULL. If there are no completions, returning a pointer
|
||||
to a NULL would work but returning NULL itself is also valid.
|
||||
WORD points in the same buffer as TEXT, and completions should be
|
||||
returned relative to this position. For example, suppose TEXT is "foo"
|
||||
and we want to complete to "foobar". If WORD is "oo", return
|
||||
"oobar"; if WORD is "baz/foo", return "baz/foobar". */
|
||||
char **(*completer) (char *text, char *word);
|
||||
|
||||
/* Type of "set" or "show" command (or SET_NOT_SET if not "set"
|
||||
or "show"). */
|
||||
cmd_types type;
|
||||
|
||||
/* Pointer to variable affected by "set" and "show". Doesn't matter
|
||||
if type is not_set. */
|
||||
void *var;
|
||||
|
||||
/* What kind of variable is *VAR? */
|
||||
var_types var_type;
|
||||
|
||||
/* Pointer to NULL terminated list of enumerated values (like argv). */
|
||||
const char **enums;
|
||||
|
||||
/* Pointer to command strings of user-defined commands */
|
||||
struct command_line *user_commands;
|
||||
|
||||
/* Pointer to command that is hooked by this one, (by hook_pre)
|
||||
so the hook can be removed when this one is deleted. */
|
||||
struct cmd_list_element *hookee_pre;
|
||||
|
||||
/* Pointer to command that is hooked by this one, (by hook_post)
|
||||
so the hook can be removed when this one is deleted. */
|
||||
struct cmd_list_element *hookee_post;
|
||||
|
||||
/* Pointer to command that is aliased by this one, so the
|
||||
aliased command can be located in case it has been hooked. */
|
||||
struct cmd_list_element *cmd_pointer;
|
||||
};
|
||||
|
||||
/* Forward-declarations of the entry-points of command.c. */
|
||||
|
||||
extern struct cmd_list_element *add_cmd (char *, enum command_class,
|
||||
void (*fun) (char *, int), char *,
|
||||
struct cmd_list_element **);
|
||||
|
||||
extern struct cmd_list_element *add_alias_cmd (char *, char *,
|
||||
enum command_class, int,
|
||||
struct cmd_list_element **);
|
||||
|
||||
extern struct cmd_list_element *add_prefix_cmd (char *, enum command_class,
|
||||
void (*fun) (char *, int),
|
||||
char *,
|
||||
struct cmd_list_element **,
|
||||
char *, int,
|
||||
struct cmd_list_element **);
|
||||
|
||||
extern struct cmd_list_element *add_abbrev_prefix_cmd (char *,
|
||||
enum command_class,
|
||||
void (*fun) (char *,
|
||||
int),
|
||||
char *,
|
||||
struct cmd_list_element
|
||||
**, char *, int,
|
||||
struct cmd_list_element
|
||||
**);
|
||||
|
||||
/* Set the commands corresponding callback. */
|
||||
|
||||
extern void set_cmd_cfunc (struct cmd_list_element *cmd,
|
||||
void (*cfunc) (char *args, int from_tty));
|
||||
|
||||
extern void set_cmd_sfunc (struct cmd_list_element *cmd,
|
||||
void (*sfunc) (char *args, int from_tty,
|
||||
struct cmd_list_element * c));
|
||||
|
||||
|
||||
extern struct cmd_list_element *lookup_cmd (char **,
|
||||
struct cmd_list_element *, char *,
|
||||
int, int);
|
||||
|
||||
extern struct cmd_list_element *lookup_cmd_1 (char **,
|
||||
struct cmd_list_element *,
|
||||
struct cmd_list_element **,
|
||||
int);
|
||||
|
||||
extern struct cmd_list_element *
|
||||
deprecate_cmd (struct cmd_list_element *, char * );
|
||||
|
||||
extern void
|
||||
deprecated_cmd_warning (char **);
|
||||
|
||||
extern int
|
||||
lookup_cmd_composition (char *text,
|
||||
struct cmd_list_element **alias,
|
||||
struct cmd_list_element **prefix_cmd,
|
||||
struct cmd_list_element **cmd);
|
||||
|
||||
extern struct cmd_list_element *add_com (char *, enum command_class,
|
||||
void (*fun) (char *, int), char *);
|
||||
|
||||
extern struct cmd_list_element *add_com_alias (char *, char *,
|
||||
enum command_class, int);
|
||||
|
||||
extern struct cmd_list_element *add_info (char *, void (*fun) (char *, int),
|
||||
char *);
|
||||
|
||||
extern struct cmd_list_element *add_info_alias (char *, char *, int);
|
||||
|
||||
extern char **complete_on_cmdlist (struct cmd_list_element *, char *, char *);
|
||||
|
||||
extern char **complete_on_enum (const char *enumlist[], char *, char *);
|
||||
|
||||
extern void delete_cmd (char *, struct cmd_list_element **);
|
||||
|
||||
extern void help_cmd (char *, struct ui_file *);
|
||||
|
||||
extern void help_list (struct cmd_list_element *, char *,
|
||||
enum command_class, struct ui_file *);
|
||||
|
||||
extern void help_cmd_list (struct cmd_list_element *, enum command_class,
|
||||
char *, int, struct ui_file *);
|
||||
|
||||
extern struct cmd_list_element *add_set_cmd (char *name, enum
|
||||
command_class class,
|
||||
var_types var_type, void *var,
|
||||
char *doc,
|
||||
struct cmd_list_element **list);
|
||||
|
||||
extern struct cmd_list_element *add_set_enum_cmd (char *name,
|
||||
enum command_class class,
|
||||
const char *enumlist[],
|
||||
const char **var,
|
||||
char *doc,
|
||||
struct cmd_list_element **list);
|
||||
|
||||
extern struct cmd_list_element *add_set_auto_boolean_cmd (char *name,
|
||||
enum command_class class,
|
||||
enum cmd_auto_boolean *var,
|
||||
char *doc,
|
||||
struct cmd_list_element **list);
|
||||
|
||||
extern struct cmd_list_element *add_set_boolean_cmd (char *name,
|
||||
enum command_class class,
|
||||
int *var,
|
||||
char *doc,
|
||||
struct cmd_list_element **list);
|
||||
|
||||
extern struct cmd_list_element *add_show_from_set (struct cmd_list_element *,
|
||||
struct cmd_list_element
|
||||
**);
|
||||
|
||||
/* Do a "show" command for each thing on a command list. */
|
||||
|
||||
extern void cmd_show_list (struct cmd_list_element *, int, char *);
|
||||
|
||||
extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
|
||||
|
||||
extern void dont_repeat (void);
|
||||
|
||||
/* Used to mark commands that don't do anything. If we just leave the
|
||||
function field NULL, the command is interpreted as a help topic, or
|
||||
as a class of commands. */
|
||||
|
||||
extern void not_just_help_class_command (char *, int);
|
||||
|
||||
#endif /* !defined (COMMAND_H) */
|
||||
168
gdb/complaints.c
168
gdb/complaints.c
@@ -1,168 +0,0 @@
|
||||
/* Support for complaint handling during symbol reading in GDB.
|
||||
Copyright 1990, 1991, 1992, 1993, 1995, 1998, 1999, 2000
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "complaints.h"
|
||||
#include "gdbcmd.h"
|
||||
|
||||
extern void _initialize_complaints (void);
|
||||
|
||||
/* Structure to manage complaints about symbol file contents. */
|
||||
|
||||
struct complaint complaint_root[1] =
|
||||
{
|
||||
{
|
||||
(char *) NULL, /* Complaint message */
|
||||
0, /* Complaint counter */
|
||||
complaint_root /* Next complaint. */
|
||||
}
|
||||
};
|
||||
|
||||
/* How many complaints about a particular thing should be printed before
|
||||
we stop whining about it? Default is no whining at all, since so many
|
||||
systems have ill-constructed symbol files. */
|
||||
|
||||
static unsigned int stop_whining = 0;
|
||||
|
||||
/* Should each complaint be self explanatory, or should we assume that
|
||||
a series of complaints is being produced?
|
||||
case 0: self explanatory message.
|
||||
case 1: First message of a series that must start off with explanation.
|
||||
case 2: Subsequent message, when user already knows we are reading
|
||||
symbols and we can just state our piece. */
|
||||
|
||||
static int complaint_series = 0;
|
||||
|
||||
|
||||
|
||||
/* Functions to handle complaints during symbol reading. */
|
||||
|
||||
/* Print a complaint about the input symbols, and link the complaint block
|
||||
into a chain for later handling. */
|
||||
|
||||
void
|
||||
complain (struct complaint *complaint,...)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, complaint);
|
||||
|
||||
complaint->counter++;
|
||||
if (complaint->next == NULL)
|
||||
{
|
||||
complaint->next = complaint_root->next;
|
||||
complaint_root->next = complaint;
|
||||
}
|
||||
if (complaint->counter > stop_whining)
|
||||
{
|
||||
return;
|
||||
}
|
||||
wrap_here ("");
|
||||
|
||||
switch (complaint_series + (info_verbose << 1))
|
||||
{
|
||||
|
||||
/* Isolated messages, must be self-explanatory. */
|
||||
case 0:
|
||||
if (warning_hook)
|
||||
(*warning_hook) (complaint->message, args);
|
||||
else
|
||||
{
|
||||
begin_line ();
|
||||
fputs_filtered ("During symbol reading, ", gdb_stderr);
|
||||
wrap_here ("");
|
||||
vfprintf_filtered (gdb_stderr, complaint->message, args);
|
||||
fputs_filtered (".\n", gdb_stderr);
|
||||
}
|
||||
break;
|
||||
|
||||
/* First of a series, without `set verbose'. */
|
||||
case 1:
|
||||
if (warning_hook)
|
||||
(*warning_hook) (complaint->message, args);
|
||||
else
|
||||
{
|
||||
begin_line ();
|
||||
fputs_filtered ("During symbol reading...", gdb_stderr);
|
||||
vfprintf_filtered (gdb_stderr, complaint->message, args);
|
||||
fputs_filtered ("...", gdb_stderr);
|
||||
wrap_here ("");
|
||||
complaint_series++;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Subsequent messages of a series, or messages under `set verbose'.
|
||||
(We'll already have produced a "Reading in symbols for XXX..."
|
||||
message and will clean up at the end with a newline.) */
|
||||
default:
|
||||
if (warning_hook)
|
||||
(*warning_hook) (complaint->message, args);
|
||||
else
|
||||
{
|
||||
vfprintf_filtered (gdb_stderr, complaint->message, args);
|
||||
fputs_filtered ("...", gdb_stderr);
|
||||
wrap_here ("");
|
||||
}
|
||||
}
|
||||
/* If GDB dumps core, we'd like to see the complaints first. Presumably
|
||||
GDB will not be sending so many complaints that this becomes a
|
||||
performance hog. */
|
||||
gdb_flush (gdb_stderr);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
/* Clear out all complaint counters that have ever been incremented.
|
||||
If sym_reading is 1, be less verbose about successive complaints,
|
||||
since the messages are appearing all together during a command that
|
||||
reads symbols (rather than scattered around as psymtabs get fleshed
|
||||
out into symtabs at random times). If noisy is 1, we are in a
|
||||
noisy symbol reading command, and our caller will print enough
|
||||
context for the user to figure it out. */
|
||||
|
||||
void
|
||||
clear_complaints (int sym_reading, int noisy)
|
||||
{
|
||||
struct complaint *p;
|
||||
|
||||
for (p = complaint_root->next; p != complaint_root; p = p->next)
|
||||
{
|
||||
p->counter = 0;
|
||||
}
|
||||
|
||||
if (!sym_reading && !noisy && complaint_series > 1 && !warning_hook)
|
||||
{
|
||||
/* Terminate previous series, since caller won't. */
|
||||
puts_filtered ("\n");
|
||||
}
|
||||
|
||||
complaint_series = sym_reading ? 1 + noisy : 0;
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_complaints (void)
|
||||
{
|
||||
add_show_from_set
|
||||
(add_set_cmd ("complaints", class_support, var_zinteger,
|
||||
(char *) &stop_whining,
|
||||
"Set max number of complaints about incorrect symbols.",
|
||||
&setlist),
|
||||
&showlist);
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/* Definitions for complaint handling during symbol reading in GDB.
|
||||
Copyright 1990, 1991, 1992, 1995, 1998, 2000
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#if !defined (COMPLAINTS_H)
|
||||
#define COMPLAINTS_H
|
||||
|
||||
|
||||
/* Support for complaining about things in the symbol file that aren't
|
||||
catastrophic.
|
||||
|
||||
Each such thing gets a counter. The first time we have the problem,
|
||||
during a symbol read, we report it. At the end of symbol reading,
|
||||
if verbose, we report how many of each problem we had. */
|
||||
|
||||
struct complaint
|
||||
{
|
||||
char *message;
|
||||
unsigned counter;
|
||||
struct complaint *next;
|
||||
};
|
||||
|
||||
/* Root of the chain of complaints that have at some point been issued.
|
||||
This is used to reset the counters, and/or report the total counts. */
|
||||
|
||||
extern struct complaint complaint_root[1];
|
||||
|
||||
/* Functions that handle complaints. (in complaints.c) */
|
||||
|
||||
extern void complain (struct complaint *, ...);
|
||||
|
||||
extern void clear_complaints (int, int);
|
||||
|
||||
|
||||
#endif /* !defined (COMPLAINTS_H) */
|
||||
695
gdb/completer.c
695
gdb/completer.c
@@ -1,695 +0,0 @@
|
||||
/* Line completion stuff for GDB, the GNU debugger.
|
||||
Copyright 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "filenames.h" /* for DOSish file names */
|
||||
|
||||
/* FIXME: This is needed because of lookup_cmd_1().
|
||||
We should be calling a hook instead so we eliminate the CLI dependency. */
|
||||
#include "gdbcmd.h"
|
||||
|
||||
/* Needed for rl_completer_word_break_characters() and for
|
||||
filename_completion_function. */
|
||||
#include <readline/readline.h>
|
||||
|
||||
/* readline defines this. */
|
||||
#undef savestring
|
||||
|
||||
#include "completer.h"
|
||||
|
||||
/* Prototypes for local functions */
|
||||
char *line_completion_function (char *text, int matches, char *line_buffer,
|
||||
int point);
|
||||
|
||||
/* readline uses the word breaks for two things:
|
||||
(1) In figuring out where to point the TEXT parameter to the
|
||||
rl_completion_entry_function. Since we don't use TEXT for much,
|
||||
it doesn't matter a lot what the word breaks are for this purpose, but
|
||||
it does affect how much stuff M-? lists.
|
||||
(2) If one of the matches contains a word break character, readline
|
||||
will quote it. That's why we switch between
|
||||
gdb_completer_word_break_characters and
|
||||
gdb_completer_command_word_break_characters. I'm not sure when
|
||||
we need this behavior (perhaps for funky characters in C++ symbols?). */
|
||||
|
||||
/* Variables which are necessary for fancy command line editing. */
|
||||
static char *gdb_completer_word_break_characters =
|
||||
" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-";
|
||||
|
||||
/* When completing on command names, we remove '-' from the list of
|
||||
word break characters, since we use it in command names. If the
|
||||
readline library sees one in any of the current completion strings,
|
||||
it thinks that the string needs to be quoted and automatically supplies
|
||||
a leading quote. */
|
||||
static char *gdb_completer_command_word_break_characters =
|
||||
" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,";
|
||||
|
||||
/* When completing on file names, we remove from the list of word
|
||||
break characters any characters that are commonly used in file
|
||||
names, such as '-', '+', '~', etc. Otherwise, readline displays
|
||||
incorrect completion candidates. */
|
||||
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
|
||||
/* MS-DOS and MS-Windows use colon as part of the drive spec, and most
|
||||
programs support @foo style response files. */
|
||||
static char *gdb_completer_file_name_break_characters = " \t\n*|\"';?><@";
|
||||
#else
|
||||
static char *gdb_completer_file_name_break_characters = " \t\n*|\"';:?><";
|
||||
#endif
|
||||
|
||||
/* These are used when completing on locations, which can mix file
|
||||
names and symbol names separated by a colon. */
|
||||
static char *gdb_completer_loc_break_characters = " \t\n*|\"';:?><,";
|
||||
|
||||
/* Characters that can be used to quote completion strings. Note that we
|
||||
can't include '"' because the gdb C parser treats such quoted sequences
|
||||
as strings. */
|
||||
static char *gdb_completer_quote_characters = "'";
|
||||
|
||||
/* Accessor for some completer data that may interest other files. */
|
||||
|
||||
char *
|
||||
get_gdb_completer_word_break_characters (void)
|
||||
{
|
||||
return gdb_completer_word_break_characters;
|
||||
}
|
||||
|
||||
char *
|
||||
get_gdb_completer_quote_characters (void)
|
||||
{
|
||||
return gdb_completer_quote_characters;
|
||||
}
|
||||
|
||||
/* Line completion interface function for readline. */
|
||||
|
||||
char *
|
||||
readline_line_completion_function (char *text, int matches)
|
||||
{
|
||||
return line_completion_function (text, matches, rl_line_buffer, rl_point);
|
||||
}
|
||||
|
||||
/* This can be used for functions which don't want to complete on symbols
|
||||
but don't want to complete on anything else either. */
|
||||
char **
|
||||
noop_completer (char *text, char *prefix)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Complete on filenames. */
|
||||
char **
|
||||
filename_completer (char *text, char *word)
|
||||
{
|
||||
int subsequent_name;
|
||||
char **return_val;
|
||||
int return_val_used;
|
||||
int return_val_alloced;
|
||||
|
||||
return_val_used = 0;
|
||||
/* Small for testing. */
|
||||
return_val_alloced = 1;
|
||||
return_val = (char **) xmalloc (return_val_alloced * sizeof (char *));
|
||||
|
||||
subsequent_name = 0;
|
||||
while (1)
|
||||
{
|
||||
char *p;
|
||||
p = filename_completion_function (text, subsequent_name);
|
||||
if (return_val_used >= return_val_alloced)
|
||||
{
|
||||
return_val_alloced *= 2;
|
||||
return_val =
|
||||
(char **) xrealloc (return_val,
|
||||
return_val_alloced * sizeof (char *));
|
||||
}
|
||||
if (p == NULL)
|
||||
{
|
||||
return_val[return_val_used++] = p;
|
||||
break;
|
||||
}
|
||||
/* We need to set subsequent_name to a non-zero value before the
|
||||
continue line below, because otherwise, if the first file seen
|
||||
by GDB is a backup file whose name ends in a `~', we will loop
|
||||
indefinitely. */
|
||||
subsequent_name = 1;
|
||||
/* Like emacs, don't complete on old versions. Especially useful
|
||||
in the "source" command. */
|
||||
if (p[strlen (p) - 1] == '~')
|
||||
continue;
|
||||
|
||||
{
|
||||
char *q;
|
||||
if (word == text)
|
||||
/* Return exactly p. */
|
||||
return_val[return_val_used++] = p;
|
||||
else if (word > text)
|
||||
{
|
||||
/* Return some portion of p. */
|
||||
q = xmalloc (strlen (p) + 5);
|
||||
strcpy (q, p + (word - text));
|
||||
return_val[return_val_used++] = q;
|
||||
xfree (p);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return some of TEXT plus p. */
|
||||
q = xmalloc (strlen (p) + (text - word) + 5);
|
||||
strncpy (q, word, text - word);
|
||||
q[text - word] = '\0';
|
||||
strcat (q, p);
|
||||
return_val[return_val_used++] = q;
|
||||
xfree (p);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* There is no way to do this just long enough to affect quote inserting
|
||||
without also affecting the next completion. This should be fixed in
|
||||
readline. FIXME. */
|
||||
/* Insure that readline does the right thing
|
||||
with respect to inserting quotes. */
|
||||
rl_completer_word_break_characters = "";
|
||||
#endif
|
||||
return return_val;
|
||||
}
|
||||
|
||||
/* Complete on locations, which might be of two possible forms:
|
||||
|
||||
file:line
|
||||
or
|
||||
symbol+offset
|
||||
|
||||
This is intended to be used in commands that set breakpoints etc. */
|
||||
char **
|
||||
location_completer (char *text, char *word)
|
||||
{
|
||||
int n_syms = 0, n_files = 0;
|
||||
char ** fn_list = NULL;
|
||||
char ** list = NULL;
|
||||
char *p;
|
||||
int quote_found = 0;
|
||||
int quoted = *text == '\'' || *text == '"';
|
||||
int quote_char = '\0';
|
||||
char *colon = NULL;
|
||||
char *file_to_match = NULL;
|
||||
char *symbol_start = text;
|
||||
char *orig_text = text;
|
||||
size_t text_len;
|
||||
|
||||
/* Do we have an unquoted colon, as in "break foo.c::bar"? */
|
||||
for (p = text; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == '\\' && p[1] == '\'')
|
||||
p++;
|
||||
else if (*p == '\'' || *p == '"')
|
||||
{
|
||||
quote_found = *p;
|
||||
quote_char = *p++;
|
||||
while (*p != '\0' && *p != quote_found)
|
||||
{
|
||||
if (*p == '\\' && p[1] == quote_found)
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p == quote_found)
|
||||
quote_found = 0;
|
||||
else
|
||||
break; /* hit the end of text */
|
||||
}
|
||||
#if HAVE_DOS_BASED_FILE_SYSTEM
|
||||
/* If we have a DOS-style absolute file name at the beginning of
|
||||
TEXT, and the colon after the drive letter is the only colon
|
||||
we found, pretend the colon is not there. */
|
||||
else if (p < text + 3 && *p == ':' && p == text + 1 + quoted)
|
||||
;
|
||||
#endif
|
||||
else if (*p == ':' && !colon)
|
||||
{
|
||||
colon = p;
|
||||
symbol_start = p + 1;
|
||||
}
|
||||
else if (strchr (gdb_completer_word_break_characters, *p))
|
||||
symbol_start = p + 1;
|
||||
}
|
||||
|
||||
if (quoted)
|
||||
text++;
|
||||
text_len = strlen (text);
|
||||
|
||||
/* Where is the file name? */
|
||||
if (colon)
|
||||
{
|
||||
char *s;
|
||||
|
||||
file_to_match = (char *) xmalloc (colon - text + 1);
|
||||
strncpy (file_to_match, text, colon - text + 1);
|
||||
/* Remove trailing colons and quotes from the file name. */
|
||||
for (s = file_to_match + (colon - text);
|
||||
s > file_to_match;
|
||||
s--)
|
||||
if (*s == ':' || *s == quote_char)
|
||||
*s = '\0';
|
||||
}
|
||||
/* If the text includes a colon, they want completion only on a
|
||||
symbol name after the colon. Otherwise, we need to complete on
|
||||
symbols as well as on files. */
|
||||
if (colon)
|
||||
{
|
||||
list = make_file_symbol_completion_list (symbol_start, word,
|
||||
file_to_match);
|
||||
xfree (file_to_match);
|
||||
}
|
||||
else
|
||||
{
|
||||
list = make_symbol_completion_list (symbol_start, word);
|
||||
/* If text includes characters which cannot appear in a file
|
||||
name, they cannot be asking for completion on files. */
|
||||
if (strcspn (text, gdb_completer_file_name_break_characters) == text_len)
|
||||
fn_list = make_source_files_completion_list (text, text);
|
||||
}
|
||||
|
||||
/* How many completions do we have in both lists? */
|
||||
if (fn_list)
|
||||
for ( ; fn_list[n_files]; n_files++)
|
||||
;
|
||||
if (list)
|
||||
for ( ; list[n_syms]; n_syms++)
|
||||
;
|
||||
|
||||
/* Make list[] large enough to hold both lists, then catenate
|
||||
fn_list[] onto the end of list[]. */
|
||||
if (n_syms && n_files)
|
||||
{
|
||||
list = xrealloc (list, (n_syms + n_files + 1) * sizeof (char *));
|
||||
memcpy (list + n_syms, fn_list, (n_files + 1) * sizeof (char *));
|
||||
xfree (fn_list);
|
||||
}
|
||||
else if (n_files)
|
||||
{
|
||||
/* If we only have file names as possible completion, we should
|
||||
bring them in sync with what rl_complete expects. The
|
||||
problem is that if the user types "break /foo/b TAB", and the
|
||||
possible completions are "/foo/bar" and "/foo/baz"
|
||||
rl_complete expects us to return "bar" and "baz", without the
|
||||
leading directories, as possible completions, because `word'
|
||||
starts at the "b". But we ignore the value of `word' when we
|
||||
call make_source_files_completion_list above (because that
|
||||
would not DTRT when the completion results in both symbols
|
||||
and file names), so make_source_files_completion_list returns
|
||||
the full "/foo/bar" and "/foo/baz" strings. This produces
|
||||
wrong results when, e.g., there's only one possible
|
||||
completion, because rl_complete will prepend "/foo/" to each
|
||||
candidate completion. The loop below removes that leading
|
||||
part. */
|
||||
for (n_files = 0; fn_list[n_files]; n_files++)
|
||||
{
|
||||
memmove (fn_list[n_files], fn_list[n_files] + (word - text),
|
||||
strlen (fn_list[n_files]) + 1 - (word - text));
|
||||
}
|
||||
/* Return just the file-name list as the result. */
|
||||
list = fn_list;
|
||||
}
|
||||
else if (!n_syms)
|
||||
{
|
||||
/* No completions at all. As the final resort, try completing
|
||||
on the entire text as a symbol. */
|
||||
list = make_symbol_completion_list (orig_text, word);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Complete on command names. Used by "help". */
|
||||
char **
|
||||
command_completer (char *text, char *word)
|
||||
{
|
||||
return complete_on_cmdlist (cmdlist, text, word);
|
||||
}
|
||||
|
||||
|
||||
/* Here are some useful test cases for completion. FIXME: These should
|
||||
be put in the test suite. They should be tested with both M-? and TAB.
|
||||
|
||||
"show output-" "radix"
|
||||
"show output" "-radix"
|
||||
"p" ambiguous (commands starting with p--path, print, printf, etc.)
|
||||
"p " ambiguous (all symbols)
|
||||
"info t foo" no completions
|
||||
"info t " no completions
|
||||
"info t" ambiguous ("info target", "info terminal", etc.)
|
||||
"info ajksdlfk" no completions
|
||||
"info ajksdlfk " no completions
|
||||
"info" " "
|
||||
"info " ambiguous (all info commands)
|
||||
"p \"a" no completions (string constant)
|
||||
"p 'a" ambiguous (all symbols starting with a)
|
||||
"p b-a" ambiguous (all symbols starting with a)
|
||||
"p b-" ambiguous (all symbols)
|
||||
"file Make" "file" (word break hard to screw up here)
|
||||
"file ../gdb.stabs/we" "ird" (needs to not break word at slash)
|
||||
*/
|
||||
|
||||
/* Generate completions one by one for the completer. Each time we are
|
||||
called return another potential completion to the caller.
|
||||
line_completion just completes on commands or passes the buck to the
|
||||
command's completer function, the stuff specific to symbol completion
|
||||
is in make_symbol_completion_list.
|
||||
|
||||
TEXT is the caller's idea of the "word" we are looking at.
|
||||
|
||||
MATCHES is the number of matches that have currently been collected from
|
||||
calling this completion function. When zero, then we need to initialize,
|
||||
otherwise the initialization has already taken place and we can just
|
||||
return the next potential completion string.
|
||||
|
||||
LINE_BUFFER is available to be looked at; it contains the entire text
|
||||
of the line. POINT is the offset in that line of the cursor. You
|
||||
should pretend that the line ends at POINT.
|
||||
|
||||
Returns NULL if there are no more completions, else a pointer to a string
|
||||
which is a possible completion, it is the caller's responsibility to
|
||||
free the string. */
|
||||
|
||||
char *
|
||||
line_completion_function (char *text, int matches, char *line_buffer, int point)
|
||||
{
|
||||
static char **list = (char **) NULL; /* Cache of completions */
|
||||
static int index; /* Next cached completion */
|
||||
char *output = NULL;
|
||||
char *tmp_command, *p;
|
||||
/* Pointer within tmp_command which corresponds to text. */
|
||||
char *word;
|
||||
struct cmd_list_element *c, *result_list;
|
||||
|
||||
if (matches == 0)
|
||||
{
|
||||
/* The caller is beginning to accumulate a new set of completions, so
|
||||
we need to find all of them now, and cache them for returning one at
|
||||
a time on future calls. */
|
||||
|
||||
if (list)
|
||||
{
|
||||
/* Free the storage used by LIST, but not by the strings inside.
|
||||
This is because rl_complete_internal () frees the strings. */
|
||||
xfree (list);
|
||||
}
|
||||
list = 0;
|
||||
index = 0;
|
||||
|
||||
/* Choose the default set of word break characters to break completions.
|
||||
If we later find out that we are doing completions on command strings
|
||||
(as opposed to strings supplied by the individual command completer
|
||||
functions, which can be any string) then we will switch to the
|
||||
special word break set for command strings, which leaves out the
|
||||
'-' character used in some commands. */
|
||||
|
||||
rl_completer_word_break_characters =
|
||||
gdb_completer_word_break_characters;
|
||||
|
||||
/* Decide whether to complete on a list of gdb commands or on symbols. */
|
||||
tmp_command = (char *) alloca (point + 1);
|
||||
p = tmp_command;
|
||||
|
||||
strncpy (tmp_command, line_buffer, point);
|
||||
tmp_command[point] = '\0';
|
||||
/* Since text always contains some number of characters leading up
|
||||
to point, we can find the equivalent position in tmp_command
|
||||
by subtracting that many characters from the end of tmp_command. */
|
||||
word = tmp_command + point - strlen (text);
|
||||
|
||||
if (point == 0)
|
||||
{
|
||||
/* An empty line we want to consider ambiguous; that is, it
|
||||
could be any command. */
|
||||
c = (struct cmd_list_element *) -1;
|
||||
result_list = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = lookup_cmd_1 (&p, cmdlist, &result_list, 1);
|
||||
}
|
||||
|
||||
/* Move p up to the next interesting thing. */
|
||||
while (*p == ' ' || *p == '\t')
|
||||
{
|
||||
p++;
|
||||
}
|
||||
|
||||
if (!c)
|
||||
{
|
||||
/* It is an unrecognized command. So there are no
|
||||
possible completions. */
|
||||
list = NULL;
|
||||
}
|
||||
else if (c == (struct cmd_list_element *) -1)
|
||||
{
|
||||
char *q;
|
||||
|
||||
/* lookup_cmd_1 advances p up to the first ambiguous thing, but
|
||||
doesn't advance over that thing itself. Do so now. */
|
||||
q = p;
|
||||
while (*q && (isalnum (*q) || *q == '-' || *q == '_'))
|
||||
++q;
|
||||
if (q != tmp_command + point)
|
||||
{
|
||||
/* There is something beyond the ambiguous
|
||||
command, so there are no possible completions. For
|
||||
example, "info t " or "info t foo" does not complete
|
||||
to anything, because "info t" can be "info target" or
|
||||
"info terminal". */
|
||||
list = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We're trying to complete on the command which was ambiguous.
|
||||
This we can deal with. */
|
||||
if (result_list)
|
||||
{
|
||||
list = complete_on_cmdlist (*result_list->prefixlist, p,
|
||||
word);
|
||||
}
|
||||
else
|
||||
{
|
||||
list = complete_on_cmdlist (cmdlist, p, word);
|
||||
}
|
||||
/* Insure that readline does the right thing with respect to
|
||||
inserting quotes. */
|
||||
rl_completer_word_break_characters =
|
||||
gdb_completer_command_word_break_characters;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We've recognized a full command. */
|
||||
|
||||
if (p == tmp_command + point)
|
||||
{
|
||||
/* There is no non-whitespace in the line beyond the command. */
|
||||
|
||||
if (p[-1] == ' ' || p[-1] == '\t')
|
||||
{
|
||||
/* The command is followed by whitespace; we need to complete
|
||||
on whatever comes after command. */
|
||||
if (c->prefixlist)
|
||||
{
|
||||
/* It is a prefix command; what comes after it is
|
||||
a subcommand (e.g. "info "). */
|
||||
list = complete_on_cmdlist (*c->prefixlist, p, word);
|
||||
|
||||
/* Insure that readline does the right thing
|
||||
with respect to inserting quotes. */
|
||||
rl_completer_word_break_characters =
|
||||
gdb_completer_command_word_break_characters;
|
||||
}
|
||||
else if (c->enums)
|
||||
{
|
||||
list = complete_on_enum (c->enums, p, word);
|
||||
rl_completer_word_break_characters =
|
||||
gdb_completer_command_word_break_characters;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It is a normal command; what comes after it is
|
||||
completed by the command's completer function. */
|
||||
if (c->completer == filename_completer)
|
||||
{
|
||||
/* Many commands which want to complete on
|
||||
file names accept several file names, as
|
||||
in "run foo bar >>baz". So we don't want
|
||||
to complete the entire text after the
|
||||
command, just the last word. To this
|
||||
end, we need to find the beginning of the
|
||||
file name by starting at `word' and going
|
||||
backwards. */
|
||||
for (p = word;
|
||||
p > tmp_command
|
||||
&& strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL;
|
||||
p--)
|
||||
;
|
||||
rl_completer_word_break_characters =
|
||||
gdb_completer_file_name_break_characters;
|
||||
}
|
||||
else if (c->completer == location_completer)
|
||||
{
|
||||
/* Commands which complete on locations want to
|
||||
see the entire argument. */
|
||||
for (p = word;
|
||||
p > tmp_command
|
||||
&& p[-1] != ' ' && p[-1] != '\t';
|
||||
p--)
|
||||
;
|
||||
}
|
||||
list = (*c->completer) (p, word);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The command is not followed by whitespace; we need to
|
||||
complete on the command itself. e.g. "p" which is a
|
||||
command itself but also can complete to "print", "ptype"
|
||||
etc. */
|
||||
char *q;
|
||||
|
||||
/* Find the command we are completing on. */
|
||||
q = p;
|
||||
while (q > tmp_command)
|
||||
{
|
||||
if (isalnum (q[-1]) || q[-1] == '-' || q[-1] == '_')
|
||||
--q;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
list = complete_on_cmdlist (result_list, q, word);
|
||||
|
||||
/* Insure that readline does the right thing
|
||||
with respect to inserting quotes. */
|
||||
rl_completer_word_break_characters =
|
||||
gdb_completer_command_word_break_characters;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is non-whitespace beyond the command. */
|
||||
|
||||
if (c->prefixlist && !c->allow_unknown)
|
||||
{
|
||||
/* It is an unrecognized subcommand of a prefix command,
|
||||
e.g. "info adsfkdj". */
|
||||
list = NULL;
|
||||
}
|
||||
else if (c->enums)
|
||||
{
|
||||
list = complete_on_enum (c->enums, p, word);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It is a normal command. */
|
||||
if (c->completer == filename_completer)
|
||||
{
|
||||
/* See the commentary above about the specifics
|
||||
of file-name completion. */
|
||||
for (p = word;
|
||||
p > tmp_command
|
||||
&& strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL;
|
||||
p--)
|
||||
;
|
||||
rl_completer_word_break_characters =
|
||||
gdb_completer_file_name_break_characters;
|
||||
}
|
||||
else if (c->completer == location_completer)
|
||||
{
|
||||
for (p = word;
|
||||
p > tmp_command
|
||||
&& p[-1] != ' ' && p[-1] != '\t';
|
||||
p--)
|
||||
;
|
||||
}
|
||||
list = (*c->completer) (p, word);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we found a list of potential completions during initialization then
|
||||
dole them out one at a time. The vector of completions is NULL
|
||||
terminated, so after returning the last one, return NULL (and continue
|
||||
to do so) each time we are called after that, until a new list is
|
||||
available. */
|
||||
|
||||
if (list)
|
||||
{
|
||||
output = list[index];
|
||||
if (output)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Can't do this because readline hasn't yet checked the word breaks
|
||||
for figuring out whether to insert a quote. */
|
||||
if (output == NULL)
|
||||
/* Make sure the word break characters are set back to normal for the
|
||||
next time that readline tries to complete something. */
|
||||
rl_completer_word_break_characters =
|
||||
gdb_completer_word_break_characters;
|
||||
#endif
|
||||
|
||||
return (output);
|
||||
}
|
||||
/* Skip over a possibly quoted word (as defined by the quote characters
|
||||
and word break characters the completer uses). Returns pointer to the
|
||||
location after the "word". */
|
||||
|
||||
char *
|
||||
skip_quoted (char *str)
|
||||
{
|
||||
char quote_char = '\0';
|
||||
char *scan;
|
||||
|
||||
for (scan = str; *scan != '\0'; scan++)
|
||||
{
|
||||
if (quote_char != '\0')
|
||||
{
|
||||
/* Ignore everything until the matching close quote char */
|
||||
if (*scan == quote_char)
|
||||
{
|
||||
/* Found matching close quote. */
|
||||
scan++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (strchr (gdb_completer_quote_characters, *scan))
|
||||
{
|
||||
/* Found start of a quoted string. */
|
||||
quote_char = *scan;
|
||||
}
|
||||
else if (strchr (gdb_completer_word_break_characters, *scan))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (scan);
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/* Header for GDB line completion.
|
||||
Copyright 2000 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (COMPLETER_H)
|
||||
#define COMPLETER_H 1
|
||||
|
||||
extern char *line_completion_function (char *, int, char *, int);
|
||||
|
||||
extern char *readline_line_completion_function (char *text, int matches);
|
||||
|
||||
extern char **noop_completer (char *, char *);
|
||||
|
||||
extern char **filename_completer (char *, char *);
|
||||
|
||||
extern char **location_completer (char *, char *);
|
||||
|
||||
extern char **command_completer (char *, char *);
|
||||
|
||||
extern char *get_gdb_completer_word_break_characters (void);
|
||||
|
||||
extern char *get_gdb_completer_quote_characters (void);
|
||||
|
||||
/* Exported to linespec.c */
|
||||
|
||||
extern char *skip_quoted (char *str);
|
||||
|
||||
#endif /* defined (COMPLETER_H) */
|
||||
498
gdb/config.in
498
gdb/config.in
@@ -1,498 +0,0 @@
|
||||
/* config.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
#undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define if you have alloca, as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if the `long double' type works. */
|
||||
#undef HAVE_LONG_DOUBLE
|
||||
|
||||
/* Define if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if you have <vfork.h>. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define as __inline if that's what the C compiler calls it. */
|
||||
#undef inline
|
||||
|
||||
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* Define if the `setpgrp' function takes no argument. */
|
||||
#undef SETPGRP_VOID
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
#undef size_t
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
#undef STAT_MACROS_BROKEN
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define vfork as fork if vfork does not work. */
|
||||
#undef vfork
|
||||
|
||||
/* Define if compiling on Solaris 7. */
|
||||
#undef _MSE_INT_H
|
||||
|
||||
/* Define if your struct reg has r_fs. */
|
||||
#undef HAVE_STRUCT_REG_R_FS
|
||||
|
||||
/* Define if your struct reg has r_gs. */
|
||||
#undef HAVE_STRUCT_REG_R_GS
|
||||
|
||||
/* Define if <link.h> exists and defines struct link_map which has
|
||||
members with an ``l_'' prefix. (For Solaris, SVR4, and
|
||||
SVR4-like systems.) */
|
||||
#undef HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS
|
||||
|
||||
/* Define if <link.h> exists and defines struct link_map which has
|
||||
members with an ``lm_'' prefix. (For SunOS.) */
|
||||
#undef HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS
|
||||
|
||||
/* Define if <link.h> exists and defines a struct so_map which has
|
||||
members with an ``som_'' prefix. (Found on older *BSD systems.) */
|
||||
#undef HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS
|
||||
|
||||
/* Define if <sys/link.h> has struct link_map32 */
|
||||
#undef HAVE_STRUCT_LINK_MAP32
|
||||
|
||||
/* Define if the prfpregset_t type is broken. */
|
||||
#undef PRFPREGSET_T_BROKEN
|
||||
|
||||
/* Define if you want to use new multi-fd /proc interface
|
||||
(replaces HAVE_MULTIPLE_PROC_FDS as well as other macros). */
|
||||
#undef NEW_PROC_API
|
||||
|
||||
/* Define if ioctl argument PIOCSET is available. */
|
||||
#undef HAVE_PROCFS_PIOCSET
|
||||
|
||||
/* Define if the `long long' type works. */
|
||||
#undef CC_HAS_LONG_LONG
|
||||
|
||||
/* Define if the "ll" format works to print long long ints. */
|
||||
#undef PRINTF_HAS_LONG_LONG
|
||||
|
||||
/* Define if the "%Lg" format works to print long doubles. */
|
||||
#undef PRINTF_HAS_LONG_DOUBLE
|
||||
|
||||
/* Define if the "%Lg" format works to scan long doubles. */
|
||||
#undef SCANF_HAS_LONG_DOUBLE
|
||||
|
||||
/* Define if using Solaris thread debugging. */
|
||||
#undef HAVE_THREAD_DB_LIB
|
||||
|
||||
/* Define on a GNU/Linux system to work around problems in sys/procfs.h. */
|
||||
#undef START_INFERIOR_TRAPS_EXPECTED
|
||||
#undef sys_quotactl
|
||||
|
||||
/* Define if you have HPUX threads */
|
||||
#undef HAVE_HPUX_THREAD_SUPPORT
|
||||
|
||||
/* Define if you want to use the memory mapped malloc package (mmalloc). */
|
||||
#undef USE_MMALLOC
|
||||
|
||||
/* Define if the runtime uses a routine from mmalloc before gdb has a chance
|
||||
to initialize mmalloc, and we want to force checking to be used anyway.
|
||||
This may cause spurious memory corruption messages if the runtime tries
|
||||
to explicitly deallocate that memory when gdb calls exit. */
|
||||
#undef MMCHECK_FORCE
|
||||
|
||||
/* Define if <proc_service.h> on solaris uses int instead of
|
||||
size_t, and assorted other type changes. */
|
||||
#undef PROC_SERVICE_IS_OLD
|
||||
|
||||
/* If you want to specify a default CPU variant, define this to be its
|
||||
name, as a C string. */
|
||||
#undef TARGET_CPU_DEFAULT
|
||||
|
||||
/* Define if the simulator is being linked in. */
|
||||
#undef WITH_SIM
|
||||
|
||||
/* Set to true if the save_state_t structure is present */
|
||||
#undef HAVE_STRUCT_SAVE_STATE_T
|
||||
|
||||
/* Set to true if the save_state_t structure has the ss_wide member */
|
||||
#undef HAVE_STRUCT_MEMBER_SS_WIDE
|
||||
|
||||
/* Define if <sys/ptrace.h> defines the PTRACE_GETREGS request. */
|
||||
#undef HAVE_PTRACE_GETREGS
|
||||
|
||||
/* Define if <sys/ptrace.h> defines the PTRACE_GETFPXREGS request. */
|
||||
#undef HAVE_PTRACE_GETFPXREGS
|
||||
|
||||
/* Define if <sys/ptrace.h> defines the PT_GETDBREGS request. */
|
||||
#undef HAVE_PT_GETDBREGS
|
||||
|
||||
/* Define if <sys/ptrace.h> defines the PT_GETXMMREGS request. */
|
||||
#undef HAVE_PT_GETXMMREGS
|
||||
|
||||
/* Define if gnu-regex.c included with GDB should be used. */
|
||||
#undef USE_INCLUDED_REGEX
|
||||
|
||||
/* BFD's default architecture. */
|
||||
#undef DEFAULT_BFD_ARCH
|
||||
|
||||
/* BFD's default target vector. */
|
||||
#undef DEFAULT_BFD_VEC
|
||||
|
||||
/* Multi-arch enabled. */
|
||||
#undef GDB_MULTI_ARCH
|
||||
|
||||
/* hostfile */
|
||||
#undef GDB_XM_FILE
|
||||
|
||||
/* targetfile */
|
||||
#undef GDB_TM_FILE
|
||||
|
||||
/* nativefile */
|
||||
#undef GDB_NM_FILE
|
||||
|
||||
/* Define if you have the __argz_count function. */
|
||||
#undef HAVE___ARGZ_COUNT
|
||||
|
||||
/* Define if you have the __argz_next function. */
|
||||
#undef HAVE___ARGZ_NEXT
|
||||
|
||||
/* Define if you have the __argz_stringify function. */
|
||||
#undef HAVE___ARGZ_STRINGIFY
|
||||
|
||||
/* Define if you have the bcopy function. */
|
||||
#undef HAVE_BCOPY
|
||||
|
||||
/* Define if you have the btowc function. */
|
||||
#undef HAVE_BTOWC
|
||||
|
||||
/* Define if you have the bzero function. */
|
||||
#undef HAVE_BZERO
|
||||
|
||||
/* Define if you have the dcgettext function. */
|
||||
#undef HAVE_DCGETTEXT
|
||||
|
||||
/* Define if you have the getcwd function. */
|
||||
#undef HAVE_GETCWD
|
||||
|
||||
/* Define if you have the getpagesize function. */
|
||||
#undef HAVE_GETPAGESIZE
|
||||
|
||||
/* Define if you have the isascii function. */
|
||||
#undef HAVE_ISASCII
|
||||
|
||||
/* Define if you have the munmap function. */
|
||||
#undef HAVE_MUNMAP
|
||||
|
||||
/* Define if you have the poll function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define if you have the putenv function. */
|
||||
#undef HAVE_PUTENV
|
||||
|
||||
/* Define if you have the realpath function. */
|
||||
#undef HAVE_REALPATH
|
||||
|
||||
/* Define if you have the sbrk function. */
|
||||
#undef HAVE_SBRK
|
||||
|
||||
/* Define if you have the setenv function. */
|
||||
#undef HAVE_SETENV
|
||||
|
||||
/* Define if you have the setlocale function. */
|
||||
#undef HAVE_SETLOCALE
|
||||
|
||||
/* Define if you have the setpgid function. */
|
||||
#undef HAVE_SETPGID
|
||||
|
||||
/* Define if you have the setpgrp function. */
|
||||
#undef HAVE_SETPGRP
|
||||
|
||||
/* Define if you have the sigaction function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define if you have the sigprocmask function. */
|
||||
#undef HAVE_SIGPROCMASK
|
||||
|
||||
/* Define if you have the sigsetmask function. */
|
||||
#undef HAVE_SIGSETMASK
|
||||
|
||||
/* Define if you have the socketpair function. */
|
||||
#undef HAVE_SOCKETPAIR
|
||||
|
||||
/* Define if you have the stpcpy function. */
|
||||
#undef HAVE_STPCPY
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define if you have the strchr function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define if you have the <argz.h> header file. */
|
||||
#undef HAVE_ARGZ_H
|
||||
|
||||
/* Define if you have the <asm/debugreg.h> header file. */
|
||||
#undef HAVE_ASM_DEBUGREG_H
|
||||
|
||||
/* Define if you have the <ctype.h> header file. */
|
||||
#undef HAVE_CTYPE_H
|
||||
|
||||
/* Define if you have the <curses.h> header file. */
|
||||
#undef HAVE_CURSES_H
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define if you have the <link.h> header file. */
|
||||
#undef HAVE_LINK_H
|
||||
|
||||
/* Define if you have the <locale.h> header file. */
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
/* Define if you have the <malloc.h> header file. */
|
||||
#undef HAVE_MALLOC_H
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define if you have the <ncurses.h> header file. */
|
||||
#undef HAVE_NCURSES_H
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define if you have the <nl_types.h> header file. */
|
||||
#undef HAVE_NL_TYPES_H
|
||||
|
||||
/* Define if you have the <nlist.h> header file. */
|
||||
#undef HAVE_NLIST_H
|
||||
|
||||
/* Define if you have the <objlist.h> header file. */
|
||||
#undef HAVE_OBJLIST_H
|
||||
|
||||
/* Define if you have the <poll.h> header file. */
|
||||
#undef HAVE_POLL_H
|
||||
|
||||
/* Define if you have the <proc_service.h> header file. */
|
||||
#undef HAVE_PROC_SERVICE_H
|
||||
|
||||
/* Define if you have the <ptrace.h> header file. */
|
||||
#undef HAVE_PTRACE_H
|
||||
|
||||
/* Define if you have the <sgtty.h> header file. */
|
||||
#undef HAVE_SGTTY_H
|
||||
|
||||
/* Define if you have the <stddef.h> header file. */
|
||||
#undef HAVE_STDDEF_H
|
||||
|
||||
/* Define if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define if you have the <sys/debugreg.h> header file. */
|
||||
#undef HAVE_SYS_DEBUGREG_H
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define if you have the <sys/fault.h> header file. */
|
||||
#undef HAVE_SYS_FAULT_H
|
||||
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define if you have the <sys/filio.h> header file. */
|
||||
#undef HAVE_SYS_FILIO_H
|
||||
|
||||
/* Define if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define if you have the <sys/poll.h> header file. */
|
||||
#undef HAVE_SYS_POLL_H
|
||||
|
||||
/* Define if you have the <sys/procfs.h> header file. */
|
||||
#undef HAVE_SYS_PROCFS_H
|
||||
|
||||
/* Define if you have the <sys/ptrace.h> header file. */
|
||||
#undef HAVE_SYS_PTRACE_H
|
||||
|
||||
/* Define if you have the <sys/reg.h> header file. */
|
||||
#undef HAVE_SYS_REG_H
|
||||
|
||||
/* Define if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define if you have the <sys/syscall.h> header file. */
|
||||
#undef HAVE_SYS_SYSCALL_H
|
||||
|
||||
/* Define if you have the <sys/user.h> header file. */
|
||||
#undef HAVE_SYS_USER_H
|
||||
|
||||
/* Define if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if you have the <term.h> header file. */
|
||||
#undef HAVE_TERM_H
|
||||
|
||||
/* Define if you have the <termio.h> header file. */
|
||||
#undef HAVE_TERMIO_H
|
||||
|
||||
/* Define if you have the <termios.h> header file. */
|
||||
#undef HAVE_TERMIOS_H
|
||||
|
||||
/* Define if you have the <thread_db.h> header file. */
|
||||
#undef HAVE_THREAD_DB_H
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#undef HAVE_TIME_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if you have the <values.h> header file. */
|
||||
#undef HAVE_VALUES_H
|
||||
|
||||
/* Define if you have the <wait.h> header file. */
|
||||
#undef HAVE_WAIT_H
|
||||
|
||||
/* Define if you have the <wchar.h> header file. */
|
||||
#undef HAVE_WCHAR_H
|
||||
|
||||
/* Define if you have the <wctype.h> header file. */
|
||||
#undef HAVE_WCTYPE_H
|
||||
|
||||
/* Define if you have the dl library (-ldl). */
|
||||
#undef HAVE_LIBDL
|
||||
|
||||
/* Define if you have the m library (-lm). */
|
||||
#undef HAVE_LIBM
|
||||
|
||||
/* Define if you have the socket library (-lsocket). */
|
||||
#undef HAVE_LIBSOCKET
|
||||
|
||||
/* Define if you have the w library (-lw). */
|
||||
#undef HAVE_LIBW
|
||||
|
||||
/* Define if you have the stpcpy function */
|
||||
#undef HAVE_STPCPY
|
||||
|
||||
/* Define if your locale.h file contains LC_MESSAGES. */
|
||||
#undef HAVE_LC_MESSAGES
|
||||
|
||||
/* Define to 1 if NLS is requested */
|
||||
#undef ENABLE_NLS
|
||||
|
||||
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
|
||||
#undef HAVE_GETTEXT
|
||||
|
||||
/* Define if sigsetjmp is available. */
|
||||
#undef HAVE_SIGSETJMP
|
||||
|
||||
/* Define if malloc is not declared in system header files. */
|
||||
#undef NEED_DECLARATION_MALLOC
|
||||
|
||||
/* Define if realloc is not declared in system header files. */
|
||||
#undef NEED_DECLARATION_REALLOC
|
||||
|
||||
/* Define if free is not declared in system header files. */
|
||||
#undef NEED_DECLARATION_FREE
|
||||
|
||||
/* Define if strerror is not declared in system header files. */
|
||||
#undef NEED_DECLARATION_STRERROR
|
||||
|
||||
/* Define if strdup is not declared in system header files. */
|
||||
#undef NEED_DECLARATION_STRDUP
|
||||
|
||||
/* Define if strstr is not declared in system header files. */
|
||||
#undef NEED_DECLARATION_STRSTR
|
||||
|
||||
/* Define if <sys/procfs.h> has pstatus_t. */
|
||||
#undef HAVE_PSTATUS_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prrun_t. */
|
||||
#undef HAVE_PRRUN_T
|
||||
|
||||
/* Define if <sys/procfs.h> has gregset_t. */
|
||||
#undef HAVE_GREGSET_T
|
||||
|
||||
/* Define if <sys/procfs.h> has fpregset_t. */
|
||||
#undef HAVE_FPREGSET_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prgregset_t. */
|
||||
#undef HAVE_PRGREGSET_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prfpregset_t. */
|
||||
#undef HAVE_PRFPREGSET_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prgregset32_t. */
|
||||
#undef HAVE_PRGREGSET32_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prfpregset32_t. */
|
||||
#undef HAVE_PRFPREGSET32_T
|
||||
|
||||
/* Define if <sys/procfs.h> has lwpid_t. */
|
||||
#undef HAVE_LWPID_T
|
||||
|
||||
/* Define if <sys/procfs.h> has psaddr_t. */
|
||||
#undef HAVE_PSADDR_T
|
||||
|
||||
/* Define if <sys/procfs.h> has prsysent_t. */
|
||||
#undef HAVE_PRSYSENT_T
|
||||
|
||||
/* Define if <sys/procfs.h> has pr_sigset_t. */
|
||||
#undef HAVE_PR_SIGSET_T
|
||||
|
||||
/* Define if <sys/procfs.h> has pr_sigaction64_t. */
|
||||
#undef HAVE_PR_SIGACTION64_T
|
||||
|
||||
/* Define if <sys/procfs.h> has pr_siginfo64_t. */
|
||||
#undef HAVE_PR_SIGINFO64_T
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# OBSOLETE # Target: AMD 29000 on EB29K board over a serial line
|
||||
# OBSOLETE TDEPFILES= a29k-tdep.o remote-udi.o udip2soc.o udr.o udi2go32.o
|
||||
# OBSOLETE TM_FILE= tm-a29k.h
|
||||
# OBSOLETE
|
||||
# OBSOLETE MT_CFLAGS = $(HOST_IPC)
|
||||
@@ -1,5 +0,0 @@
|
||||
# OBSOLETE # Target: AMD 29000
|
||||
# OBSOLETE TDEPFILES= a29k-tdep.o remote-eb.o remote-adapt.o
|
||||
# OBSOLETE TM_FILE= tm-a29k.h
|
||||
# OBSOLETE
|
||||
# OBSOLETE MT_CFLAGS = -DNO_HIF_SUPPORT
|
||||
@@ -1,722 +0,0 @@
|
||||
/* OBSOLETE /* Parameters for target machine AMD 29000, for GDB, the GNU debugger. */
|
||||
/* OBSOLETE Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, */
|
||||
/* OBSOLETE 2001 Free Software Foundation, Inc. */
|
||||
/* OBSOLETE Contributed by Cygnus Support. Written by Jim Kingdon. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE This file is part of GDB. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE This program is free software; you can redistribute it and/or modify */
|
||||
/* OBSOLETE it under the terms of the GNU General Public License as published by */
|
||||
/* OBSOLETE the Free Software Foundation; either version 2 of the License, or */
|
||||
/* OBSOLETE (at your option) any later version. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE This program is distributed in the hope that it will be useful, */
|
||||
/* OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* OBSOLETE GNU General Public License for more details. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE You should have received a copy of the GNU General Public License */
|
||||
/* OBSOLETE along with this program; if not, write to the Free Software */
|
||||
/* OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, */
|
||||
/* OBSOLETE Boston, MA 02111-1307, USA. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #include "regcache.h" */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Parameters for an EB29K (a board which plugs into a PC and is */
|
||||
/* OBSOLETE accessed through EBMON software running on the PC, which we */
|
||||
/* OBSOLETE use as we'd use a remote stub (see remote-eb.c). */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE If gdb is ported to other a29k machines/systems, the */
|
||||
/* OBSOLETE machine/system-specific parts should be removed from this file (a */
|
||||
/* OBSOLETE la tm-m68k.h). */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Byte order is configurable, but this machine runs big-endian. */ */
|
||||
/* OBSOLETE #define TARGET_BYTE_ORDER BFD_ENDIAN_BIG */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Floating point uses IEEE representations. */ */
|
||||
/* OBSOLETE #define IEEE_FLOAT (1) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Recognize our magic number. */ */
|
||||
/* OBSOLETE #define BADMAG(x) ((x).f_magic != 0572) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Offset from address of function to start of its code. */
|
||||
/* OBSOLETE Zero on most machines. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define FUNCTION_START_OFFSET 0 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Advance PC across any function entry prologue instructions */
|
||||
/* OBSOLETE to reach some "real" code. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define SKIP_PROLOGUE(pc) (a29k_skip_prologue (pc)) */
|
||||
/* OBSOLETE CORE_ADDR a29k_skip_prologue (); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Immediately after a function call, return the saved pc. */
|
||||
/* OBSOLETE Can't go through the frames for this because on some machines */
|
||||
/* OBSOLETE the new frame is not set up until the new function executes */
|
||||
/* OBSOLETE some instructions. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define SAVED_PC_AFTER_CALL(frame) ((frame->flags & TRANSPARENT_FRAME) \ */
|
||||
/* OBSOLETE ? read_register (TPC_REGNUM) \ */
|
||||
/* OBSOLETE : read_register (LR0_REGNUM)) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Stack grows downward. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define INNER_THAN(lhs,rhs) ((lhs) < (rhs)) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Stack must be aligned on 32-bit boundaries when synthesizing */
|
||||
/* OBSOLETE function calls. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define STACK_ALIGN(ADDR) (((ADDR) + 3) & ~3) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Sequence of bytes for breakpoint instruction. */ */
|
||||
/* OBSOLETE /* ASNEQ 0x50, gr1, gr1 */
|
||||
/* OBSOLETE The trap number 0x50 is chosen arbitrarily. */
|
||||
/* OBSOLETE We let the command line (or previously included files) override this */
|
||||
/* OBSOLETE setting. */ */
|
||||
/* OBSOLETE #ifndef BREAKPOINT */
|
||||
/* OBSOLETE #if TARGET_BYTE_ORDER == BFD_ENDIAN_BIG */
|
||||
/* OBSOLETE #define BREAKPOINT {0x72, 0x50, 0x01, 0x01} */
|
||||
/* OBSOLETE #else /* Target is little-endian. */ */
|
||||
/* OBSOLETE #define BREAKPOINT {0x01, 0x01, 0x50, 0x72} */
|
||||
/* OBSOLETE #endif /* Target is little-endian. */ */
|
||||
/* OBSOLETE #endif /* BREAKPOINT */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Amount PC must be decremented by after a breakpoint. */
|
||||
/* OBSOLETE This is often the number of bytes in BREAKPOINT */
|
||||
/* OBSOLETE but not always. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define DECR_PC_AFTER_BREAK 0 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Say how long (ordinary) registers are. This is a piece of bogosity */
|
||||
/* OBSOLETE used in push_word and a few other places; REGISTER_RAW_SIZE is the */
|
||||
/* OBSOLETE real way to know how big a register is. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define REGISTER_SIZE 4 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Allow the register declarations here to be overridden for remote */
|
||||
/* OBSOLETE kernel debugging. */ */
|
||||
/* OBSOLETE #if !defined (REGISTER_NAMES) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Number of machine registers */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define NUM_REGS 205 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Initializer for an array of names of registers. */
|
||||
/* OBSOLETE There should be NUM_REGS strings in this initializer. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE FIXME, add floating point registers and support here. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE Also note that this list does not attempt to deal with kernel */
|
||||
/* OBSOLETE debugging (in which the first 32 registers are gr64-gr95). */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define REGISTER_NAMES \ */
|
||||
/* OBSOLETE {"gr96", "gr97", "gr98", "gr99", "gr100", "gr101", "gr102", "gr103", "gr104", \ */
|
||||
/* OBSOLETE "gr105", "gr106", "gr107", "gr108", "gr109", "gr110", "gr111", "gr112", \ */
|
||||
/* OBSOLETE "gr113", "gr114", "gr115", "gr116", "gr117", "gr118", "gr119", "gr120", \ */
|
||||
/* OBSOLETE "gr121", "gr122", "gr123", "gr124", "gr125", "gr126", "gr127", \ */
|
||||
/* OBSOLETE "lr0", "lr1", "lr2", "lr3", "lr4", "lr5", "lr6", "lr7", "lr8", "lr9", \ */
|
||||
/* OBSOLETE "lr10", "lr11", "lr12", "lr13", "lr14", "lr15", "lr16", "lr17", "lr18", \ */
|
||||
/* OBSOLETE "lr19", "lr20", "lr21", "lr22", "lr23", "lr24", "lr25", "lr26", "lr27", \ */
|
||||
/* OBSOLETE "lr28", "lr29", "lr30", "lr31", "lr32", "lr33", "lr34", "lr35", "lr36", \ */
|
||||
/* OBSOLETE "lr37", "lr38", "lr39", "lr40", "lr41", "lr42", "lr43", "lr44", "lr45", \ */
|
||||
/* OBSOLETE "lr46", "lr47", "lr48", "lr49", "lr50", "lr51", "lr52", "lr53", "lr54", \ */
|
||||
/* OBSOLETE "lr55", "lr56", "lr57", "lr58", "lr59", "lr60", "lr61", "lr62", "lr63", \ */
|
||||
/* OBSOLETE "lr64", "lr65", "lr66", "lr67", "lr68", "lr69", "lr70", "lr71", "lr72", \ */
|
||||
/* OBSOLETE "lr73", "lr74", "lr75", "lr76", "lr77", "lr78", "lr79", "lr80", "lr81", \ */
|
||||
/* OBSOLETE "lr82", "lr83", "lr84", "lr85", "lr86", "lr87", "lr88", "lr89", "lr90", \ */
|
||||
/* OBSOLETE "lr91", "lr92", "lr93", "lr94", "lr95", "lr96", "lr97", "lr98", "lr99", \ */
|
||||
/* OBSOLETE "lr100", "lr101", "lr102", "lr103", "lr104", "lr105", "lr106", "lr107", \ */
|
||||
/* OBSOLETE "lr108", "lr109", "lr110", "lr111", "lr112", "lr113", "lr114", "lr115", \ */
|
||||
/* OBSOLETE "lr116", "lr117", "lr118", "lr119", "lr120", "lr121", "lr122", "lr123", \ */
|
||||
/* OBSOLETE "lr124", "lr125", "lr126", "lr127", \ */
|
||||
/* OBSOLETE "AI0", "AI1", "AI2", "AI3", "AI4", "AI5", "AI6", "AI7", "AI8", "AI9", \ */
|
||||
/* OBSOLETE "AI10", "AI11", "AI12", "AI13", "AI14", "AI15", "FP", \ */
|
||||
/* OBSOLETE "bp", "fc", "cr", "q", \ */
|
||||
/* OBSOLETE "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr", \ */
|
||||
/* OBSOLETE "pc0", "pc1", "pc2", "mmu", "lru", "fpe", "inte", "fps", "exo", "gr1", \ */
|
||||
/* OBSOLETE "alu", "ipc", "ipa", "ipb" } */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* */
|
||||
/* OBSOLETE * Converts an sdb register number to an internal gdb register number. */
|
||||
/* OBSOLETE * Currently under epi, gr96->0...gr127->31...lr0->32...lr127->159, or... */
|
||||
/* OBSOLETE * gr64->0...gr95->31, lr0->32...lr127->159. */
|
||||
/* OBSOLETE */ */
|
||||
/* OBSOLETE #define SDB_REG_TO_REGNUM(value) \ */
|
||||
/* OBSOLETE (((value) >= 96 && (value) <= 127) ? ((value) - 96) : \ */
|
||||
/* OBSOLETE ((value) >= 128 && (value) <= 255) ? ((value) - 128 + LR0_REGNUM) : \ */
|
||||
/* OBSOLETE (value)) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* */
|
||||
/* OBSOLETE * Provide the processor register numbers of some registers that are */
|
||||
/* OBSOLETE * expected/written in instructions that might change under different */
|
||||
/* OBSOLETE * register sets. Namely, gcc can compile (-mkernel-registers) so that */
|
||||
/* OBSOLETE * it uses gr64-gr95 in stead of gr96-gr127. */
|
||||
/* OBSOLETE */ */
|
||||
/* OBSOLETE #define MSP_HW_REGNUM 125 /* gr125 */ */
|
||||
/* OBSOLETE #define RAB_HW_REGNUM 126 /* gr126 */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Convert Processor Special register #x to REGISTER_NAMES register # */ */
|
||||
/* OBSOLETE #define SR_REGNUM(x) \ */
|
||||
/* OBSOLETE ((x) < 15 ? VAB_REGNUM + (x) \ */
|
||||
/* OBSOLETE : (x) >= 128 && (x) < 131 ? IPC_REGNUM + (x) - 128 \ */
|
||||
/* OBSOLETE : (x) == 131 ? Q_REGNUM \ */
|
||||
/* OBSOLETE : (x) == 132 ? ALU_REGNUM \ */
|
||||
/* OBSOLETE : (x) >= 133 && (x) < 136 ? BP_REGNUM + (x) - 133 \ */
|
||||
/* OBSOLETE : (x) >= 160 && (x) < 163 ? FPE_REGNUM + (x) - 160 \ */
|
||||
/* OBSOLETE : (x) == 164 ? EXO_REGNUM \ */
|
||||
/* OBSOLETE : (error ("Internal error in SR_REGNUM"), 0)) */
|
||||
/* OBSOLETE #define GR96_REGNUM 0 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Define the return register separately, so it can be overridden for */
|
||||
/* OBSOLETE kernel procedure calling conventions. */ */
|
||||
/* OBSOLETE #define RETURN_REGNUM GR96_REGNUM */
|
||||
/* OBSOLETE #define GR1_REGNUM 200 */
|
||||
/* OBSOLETE /* This needs to be the memory stack pointer, not the register stack pointer, */
|
||||
/* OBSOLETE to make call_function work right. */ */
|
||||
/* OBSOLETE #define SP_REGNUM MSP_REGNUM */
|
||||
/* OBSOLETE #define FP_REGNUM 33 /* lr1 */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Return register for transparent calling convention (gr122). */ */
|
||||
/* OBSOLETE #define TPC_REGNUM (122 - 96 + GR96_REGNUM) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Large Return Pointer (gr123). */ */
|
||||
/* OBSOLETE #define LRP_REGNUM (123 - 96 + GR96_REGNUM) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Static link pointer (gr124). */ */
|
||||
/* OBSOLETE #define SLP_REGNUM (124 - 96 + GR96_REGNUM) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Memory Stack Pointer (gr125). */ */
|
||||
/* OBSOLETE #define MSP_REGNUM (125 - 96 + GR96_REGNUM) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Register allocate bound (gr126). */ */
|
||||
/* OBSOLETE #define RAB_REGNUM (126 - 96 + GR96_REGNUM) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Register Free Bound (gr127). */ */
|
||||
/* OBSOLETE #define RFB_REGNUM (127 - 96 + GR96_REGNUM) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Register Stack Pointer. */ */
|
||||
/* OBSOLETE #define RSP_REGNUM GR1_REGNUM */
|
||||
/* OBSOLETE #define LR0_REGNUM 32 */
|
||||
/* OBSOLETE #define BP_REGNUM 177 */
|
||||
/* OBSOLETE #define FC_REGNUM 178 */
|
||||
/* OBSOLETE #define CR_REGNUM 179 */
|
||||
/* OBSOLETE #define Q_REGNUM 180 */
|
||||
/* OBSOLETE #define VAB_REGNUM 181 */
|
||||
/* OBSOLETE #define OPS_REGNUM (VAB_REGNUM + 1) */
|
||||
/* OBSOLETE #define CPS_REGNUM (VAB_REGNUM + 2) */
|
||||
/* OBSOLETE #define CFG_REGNUM (VAB_REGNUM + 3) */
|
||||
/* OBSOLETE #define CHA_REGNUM (VAB_REGNUM + 4) */
|
||||
/* OBSOLETE #define CHD_REGNUM (VAB_REGNUM + 5) */
|
||||
/* OBSOLETE #define CHC_REGNUM (VAB_REGNUM + 6) */
|
||||
/* OBSOLETE #define RBP_REGNUM (VAB_REGNUM + 7) */
|
||||
/* OBSOLETE #define TMC_REGNUM (VAB_REGNUM + 8) */
|
||||
/* OBSOLETE #define TMR_REGNUM (VAB_REGNUM + 9) */
|
||||
/* OBSOLETE #define NPC_REGNUM (VAB_REGNUM + 10) /* pc0 */ */
|
||||
/* OBSOLETE #define PC_REGNUM (VAB_REGNUM + 11) /* pc1 */ */
|
||||
/* OBSOLETE #define PC2_REGNUM (VAB_REGNUM + 12) */
|
||||
/* OBSOLETE #define MMU_REGNUM (VAB_REGNUM + 13) */
|
||||
/* OBSOLETE #define LRU_REGNUM (VAB_REGNUM + 14) */
|
||||
/* OBSOLETE #define FPE_REGNUM (VAB_REGNUM + 15) */
|
||||
/* OBSOLETE #define INTE_REGNUM (VAB_REGNUM + 16) */
|
||||
/* OBSOLETE #define FPS_REGNUM (VAB_REGNUM + 17) */
|
||||
/* OBSOLETE #define EXO_REGNUM (VAB_REGNUM + 18) */
|
||||
/* OBSOLETE /* gr1 is defined above as 200 = VAB_REGNUM + 19 */ */
|
||||
/* OBSOLETE #define ALU_REGNUM (VAB_REGNUM + 20) */
|
||||
/* OBSOLETE #define PS_REGNUM ALU_REGNUM */
|
||||
/* OBSOLETE #define IPC_REGNUM (VAB_REGNUM + 21) */
|
||||
/* OBSOLETE #define IPA_REGNUM (VAB_REGNUM + 22) */
|
||||
/* OBSOLETE #define IPB_REGNUM (VAB_REGNUM + 23) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #endif /* !defined(REGISTER_NAMES) */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Total amount of space needed to store our copies of the machine's */
|
||||
/* OBSOLETE register state, the array `registers'. */ */
|
||||
/* OBSOLETE #define REGISTER_BYTES (NUM_REGS * 4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Index within `registers' of the first byte of the space for */
|
||||
/* OBSOLETE register N. */ */
|
||||
/* OBSOLETE #define REGISTER_BYTE(N) ((N)*4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Number of bytes of storage in the actual machine representation */
|
||||
/* OBSOLETE for register N. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* All regs are 4 bytes. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define REGISTER_RAW_SIZE(N) (4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Number of bytes of storage in the program's representation */
|
||||
/* OBSOLETE for register N. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* All regs are 4 bytes. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define REGISTER_VIRTUAL_SIZE(N) (4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Largest value REGISTER_RAW_SIZE can have. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define MAX_REGISTER_RAW_SIZE (4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Largest value REGISTER_VIRTUAL_SIZE can have. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define MAX_REGISTER_VIRTUAL_SIZE (4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Return the GDB type object for the "standard" data type */
|
||||
/* OBSOLETE of data in register N. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define REGISTER_VIRTUAL_TYPE(N) \ */
|
||||
/* OBSOLETE (((N) == PC_REGNUM || (N) == LRP_REGNUM || (N) == SLP_REGNUM \ */
|
||||
/* OBSOLETE || (N) == MSP_REGNUM || (N) == RAB_REGNUM || (N) == RFB_REGNUM \ */
|
||||
/* OBSOLETE || (N) == GR1_REGNUM || (N) == FP_REGNUM || (N) == LR0_REGNUM \ */
|
||||
/* OBSOLETE || (N) == NPC_REGNUM || (N) == PC2_REGNUM) \ */
|
||||
/* OBSOLETE ? lookup_pointer_type (builtin_type_void) : builtin_type_int) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Store the address of the place in which to copy the structure the */
|
||||
/* OBSOLETE subroutine will return. This is called from call_function. */ */
|
||||
/* OBSOLETE /* On the a29k the LRP points to the part of the structure beyond the first */
|
||||
/* OBSOLETE 16 words. */ */
|
||||
/* OBSOLETE #define STORE_STRUCT_RETURN(ADDR, SP) \ */
|
||||
/* OBSOLETE write_register (LRP_REGNUM, (ADDR) + 16 * 4); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Should call_function allocate stack space for a struct return? */ */
|
||||
/* OBSOLETE /* On the a29k objects over 16 words require the caller to allocate space. */ */
|
||||
/* OBSOLETE extern use_struct_convention_fn a29k_use_struct_convention; */
|
||||
/* OBSOLETE #define USE_STRUCT_CONVENTION(gcc_p, type) a29k_use_struct_convention (gcc_p, type) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Extract from an array REGBUF containing the (raw) register state */
|
||||
/* OBSOLETE a function return value of type TYPE, and copy that, in virtual format, */
|
||||
/* OBSOLETE into VALBUF. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ */
|
||||
/* OBSOLETE { \ */
|
||||
/* OBSOLETE int reg_length = TYPE_LENGTH (TYPE); \ */
|
||||
/* OBSOLETE if (reg_length > 16 * 4) \ */
|
||||
/* OBSOLETE { \ */
|
||||
/* OBSOLETE reg_length = 16 * 4; \ */
|
||||
/* OBSOLETE read_memory (*((int *)(REGBUF) + LRP_REGNUM), (VALBUF) + 16 * 4, \ */
|
||||
/* OBSOLETE TYPE_LENGTH (TYPE) - 16 * 4); \ */
|
||||
/* OBSOLETE } \ */
|
||||
/* OBSOLETE memcpy ((VALBUF), ((int *)(REGBUF))+RETURN_REGNUM, reg_length); \ */
|
||||
/* OBSOLETE } */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Write into appropriate registers a function return value */
|
||||
/* OBSOLETE of type TYPE, given in virtual format. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define STORE_RETURN_VALUE(TYPE,VALBUF) \ */
|
||||
/* OBSOLETE { \ */
|
||||
/* OBSOLETE int reg_length = TYPE_LENGTH (TYPE); \ */
|
||||
/* OBSOLETE if (reg_length > 16 * 4) \ */
|
||||
/* OBSOLETE { \ */
|
||||
/* OBSOLETE reg_length = 16 * 4; \ */
|
||||
/* OBSOLETE write_memory (read_register (LRP_REGNUM), \ */
|
||||
/* OBSOLETE (char *)(VALBUF) + 16 * 4, \ */
|
||||
/* OBSOLETE TYPE_LENGTH (TYPE) - 16 * 4); \ */
|
||||
/* OBSOLETE } \ */
|
||||
/* OBSOLETE write_register_bytes (REGISTER_BYTE (RETURN_REGNUM), (char *)(VALBUF), \ */
|
||||
/* OBSOLETE TYPE_LENGTH (TYPE)); \ */
|
||||
/* OBSOLETE } */
|
||||
/* OBSOLETE /* *INDENT-OFF* */ */
|
||||
/* OBSOLETE /* The a29k user's guide documents well what the stacks look like. */
|
||||
/* OBSOLETE But what isn't so clear there is how this interracts with the */
|
||||
/* OBSOLETE symbols, or with GDB. */
|
||||
/* OBSOLETE In the following saved_msp, saved memory stack pointer (which functions */
|
||||
/* OBSOLETE as a memory frame pointer), means either */
|
||||
/* OBSOLETE a register containing the memory frame pointer or, in the case of */
|
||||
/* OBSOLETE functions with fixed size memory frames (i.e. those who don't use */
|
||||
/* OBSOLETE alloca()), the result of the calculation msp + msize. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE LOC_ARG, LOC_LOCAL - For GCC, these are relative to saved_msp. */
|
||||
/* OBSOLETE For high C, these are relative to msp (making alloca impossible). */
|
||||
/* OBSOLETE LOC_REGISTER, LOC_REGPARM - The register number is the number at the */
|
||||
/* OBSOLETE time the function is running (after the prologue), or in the case */
|
||||
/* OBSOLETE of LOC_REGPARM, may be a register number in the range 160-175. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE The compilers do things like store an argument into memory, and then put out */
|
||||
/* OBSOLETE a LOC_ARG for it, or put it into global registers and put out a */
|
||||
/* OBSOLETE LOC_REGPARM. Thus is it important to execute the first line of */
|
||||
/* OBSOLETE code (i.e. the line of the open brace, i.e. the prologue) of a function */
|
||||
/* OBSOLETE before trying to print arguments or anything. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE The following diagram attempts to depict what is going on in memory */
|
||||
/* OBSOLETE (see also the _a29k user's guide_) and also how that interacts with */
|
||||
/* OBSOLETE GDB frames. We arbitrarily pick fci->frame to point the same place */
|
||||
/* OBSOLETE as the register stack pointer; since we set it ourself in */
|
||||
/* OBSOLETE INIT_EXTRA_FRAME_INFO, and access it only through the FRAME_* */
|
||||
/* OBSOLETE macros, it doesn't really matter exactly how we */
|
||||
/* OBSOLETE do it. However, note that FRAME_FP is used in two ways in GDB: */
|
||||
/* OBSOLETE (1) as a "magic cookie" which uniquely identifies frames (even over */
|
||||
/* OBSOLETE calls to the inferior), (2) (in PC_IN_CALL_DUMMY [ON_STACK]) */
|
||||
/* OBSOLETE as the value of SP_REGNUM before the dummy frame was pushed. These */
|
||||
/* OBSOLETE two meanings would be incompatible for the a29k if we defined */
|
||||
/* OBSOLETE CALL_DUMMY_LOCATION == ON_STACK (but we don't, so don't worry about it). */
|
||||
/* OBSOLETE Also note that "lr1" below, while called a frame pointer */
|
||||
/* OBSOLETE in the user's guide, has only one function: To determine whether */
|
||||
/* OBSOLETE registers need to be filled in the function epilogue. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE Consider the code: */
|
||||
/* OBSOLETE < call bar> */
|
||||
/* OBSOLETE loc1: . . . */
|
||||
/* OBSOLETE bar: sub gr1,gr1,rsize_b */
|
||||
/* OBSOLETE . . . */
|
||||
/* OBSOLETE add mfp,msp,0 */
|
||||
/* OBSOLETE sub msp,msp,msize_b */
|
||||
/* OBSOLETE . . . */
|
||||
/* OBSOLETE < call foo > */
|
||||
/* OBSOLETE loc2: . . . */
|
||||
/* OBSOLETE foo: sub gr1,gr1,rsize_f */
|
||||
/* OBSOLETE . . . */
|
||||
/* OBSOLETE add mfp,msp,0 */
|
||||
/* OBSOLETE sub msp,msp,msize_f */
|
||||
/* OBSOLETE . . . */
|
||||
/* OBSOLETE loc3: < suppose the inferior stops here > */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE memory stack register stack */
|
||||
/* OBSOLETE | | |____________| */
|
||||
/* OBSOLETE | | |____loc1____| */
|
||||
/* OBSOLETE +------->|___________| | | ^ */
|
||||
/* OBSOLETE | | ^ | | locals_b | | */
|
||||
/* OBSOLETE | | | | |____________| | */
|
||||
/* OBSOLETE | | | | | | | rsize_b */
|
||||
/* OBSOLETE | | | msize_b | | args_to_f | | */
|
||||
/* OBSOLETE | | | | |____________| | */
|
||||
/* OBSOLETE | | | | |____lr1_____| V */
|
||||
/* OBSOLETE | | V | |____loc2____|<----------------+ */
|
||||
/* OBSOLETE | +--->|___________|<---------mfp | ^ | */
|
||||
/* OBSOLETE | | | ^ | | locals_f | | | */
|
||||
/* OBSOLETE | | | | msize_f | |____________| | | */
|
||||
/* OBSOLETE | | | | | | | | rsize_f | */
|
||||
/* OBSOLETE | | | V | | args | | | */
|
||||
/* OBSOLETE | | |___________|<msp |____________| | | */
|
||||
/* OBSOLETE | | |_____lr1____| V | */
|
||||
/* OBSOLETE | | |___garbage__| <- gr1 <----+ | */
|
||||
/* OBSOLETE | | | | */
|
||||
/* OBSOLETE | | | | */
|
||||
/* OBSOLETE | | pc=loc3 | | */
|
||||
/* OBSOLETE | | | | */
|
||||
/* OBSOLETE | | | | */
|
||||
/* OBSOLETE | | frame cache | | */
|
||||
/* OBSOLETE | | |_________________| | | */
|
||||
/* OBSOLETE | | |rsize=rsize_b | | | */
|
||||
/* OBSOLETE | | |msize=msize_b | | | */
|
||||
/* OBSOLETE +---|--------saved_msp | | | */
|
||||
/* OBSOLETE | |frame------------------------------------|---+ */
|
||||
/* OBSOLETE | |pc=loc2 | | */
|
||||
/* OBSOLETE | |_________________| | */
|
||||
/* OBSOLETE | |rsize=rsize_f | | */
|
||||
/* OBSOLETE | |msize=msize_f | | */
|
||||
/* OBSOLETE +--------saved_msp | | */
|
||||
/* OBSOLETE |frame------------------------------------+ */
|
||||
/* OBSOLETE |pc=loc3 | */
|
||||
/* OBSOLETE |_________________| */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE So, is that sufficiently confusing? Welcome to the 29000. */
|
||||
/* OBSOLETE Notes: */
|
||||
/* OBSOLETE * The frame for foo uses a memory frame pointer but the frame for */
|
||||
/* OBSOLETE bar does not. In the latter case the saved_msp is */
|
||||
/* OBSOLETE computed by adding msize to the saved_msp of the */
|
||||
/* OBSOLETE next frame. */
|
||||
/* OBSOLETE * msize is in the frame cache only for high C's sake. */ */
|
||||
/* OBSOLETE /* *INDENT-ON* */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE void read_register_stack (); */
|
||||
/* OBSOLETE long read_register_stack_integer (); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define FRAME_INIT_SAVED_REGS(fi) /*no-op */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define EXTRA_FRAME_INFO \ */
|
||||
/* OBSOLETE CORE_ADDR saved_msp; \ */
|
||||
/* OBSOLETE unsigned int rsize; \ */
|
||||
/* OBSOLETE unsigned int msize; \ */
|
||||
/* OBSOLETE unsigned char flags; */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Bits for flags in EXTRA_FRAME_INFO */ */
|
||||
/* OBSOLETE #define TRANSPARENT_FRAME 0x1 /* This is a transparent frame */ */
|
||||
/* OBSOLETE #define MFP_USED 0x2 /* A memory frame pointer is used */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Because INIT_FRAME_PC gets passed fromleaf, that's where we init */
|
||||
/* OBSOLETE not only ->pc and ->frame, but all the extra stuff, when called from */
|
||||
/* OBSOLETE get_prev_frame, that is. */ */
|
||||
/* OBSOLETE #define INIT_EXTRA_FRAME_INFO(fromleaf, fci) init_extra_frame_info(fci) */
|
||||
/* OBSOLETE void init_extra_frame_info (); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define INIT_FRAME_PC(fromleaf, fci) init_frame_pc(fromleaf, fci) */
|
||||
/* OBSOLETE void init_frame_pc (); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* FRAME_CHAIN takes a FRAME */
|
||||
/* OBSOLETE and produces the frame's chain-pointer. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE However, if FRAME_CHAIN_VALID returns zero, */
|
||||
/* OBSOLETE it means the given frame is the outermost one and has no caller. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* On the a29k, the nominal address of a frame is the address on the */
|
||||
/* OBSOLETE register stack of the return address (the one next to the incoming */
|
||||
/* OBSOLETE arguments, not down at the bottom so nominal address == stack pointer). */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE GDB expects "nominal address" to equal contents of FP_REGNUM, */
|
||||
/* OBSOLETE at least when it comes time to create the innermost frame. */
|
||||
/* OBSOLETE However, that doesn't work for us, so when creating the innermost */
|
||||
/* OBSOLETE frame we set ->frame ourselves in INIT_EXTRA_FRAME_INFO. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* These are mostly dummies for the a29k because INIT_FRAME_PC */
|
||||
/* OBSOLETE sets prev->frame instead. */ */
|
||||
/* OBSOLETE /* If rsize is zero, we must be at end of stack (or otherwise hosed). */
|
||||
/* OBSOLETE If we don't check rsize, we loop forever if we see rsize == 0. */ */
|
||||
/* OBSOLETE #define FRAME_CHAIN(thisframe) \ */
|
||||
/* OBSOLETE ((thisframe)->rsize == 0 \ */
|
||||
/* OBSOLETE ? 0 \ */
|
||||
/* OBSOLETE : (thisframe)->frame + (thisframe)->rsize) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Determine if the frame has a 'previous' and back-traceable frame. */ */
|
||||
/* OBSOLETE #define FRAME_IS_UNCHAINED(frame) ((frame)->flags & TRANSPARENT_FRAME) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Find the previous frame of a transparent routine. */
|
||||
/* OBSOLETE * For now lets not try and trace through a transparent routine (we might */
|
||||
/* OBSOLETE * have to assume that all transparent routines are traps). */
|
||||
/* OBSOLETE */ */
|
||||
/* OBSOLETE #define FIND_PREV_UNCHAINED_FRAME(frame) 0 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Define other aspects of the stack frame. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* An expression that tells us whether the function invocation represented */
|
||||
/* OBSOLETE by FI does not have a frame on the stack associated with it. */ */
|
||||
/* OBSOLETE #define FRAMELESS_FUNCTION_INVOCATION(FI) \ */
|
||||
/* OBSOLETE (frameless_look_for_prologue (FI)) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Saved pc (i.e. return address). */ */
|
||||
/* OBSOLETE #define FRAME_SAVED_PC(fraim) \ */
|
||||
/* OBSOLETE (read_register_stack_integer ((fraim)->frame + (fraim)->rsize, 4)) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Local variables (i.e. LOC_LOCAL) are on the memory stack, with their */
|
||||
/* OBSOLETE offsets being relative to the memory stack pointer (high C) or */
|
||||
/* OBSOLETE saved_msp (gcc). */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define FRAME_LOCALS_ADDRESS(fi) frame_locals_address (fi) */
|
||||
/* OBSOLETE extern CORE_ADDR frame_locals_address (); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Return number of args passed to a frame. */
|
||||
/* OBSOLETE Can return -1, meaning no way to tell. */ */
|
||||
/* OBSOLETE /* We tried going to the effort of finding the tags word and getting */
|
||||
/* OBSOLETE the argcount field from it, to support debugging assembler code. */
|
||||
/* OBSOLETE Problem was, the "argcount" field never did hold the argument */
|
||||
/* OBSOLETE count. */ */
|
||||
/* OBSOLETE #define FRAME_NUM_ARGS(fi) (-1) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define FRAME_ARGS_ADDRESS(fi) FRAME_LOCALS_ADDRESS (fi) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Return number of bytes at start of arglist that are not really args. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define FRAME_ARGS_SKIP 0 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Provide our own get_saved_register. HAVE_REGISTER_WINDOWS is insufficient */
|
||||
/* OBSOLETE because registers get renumbered on the a29k without getting saved. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE struct frame_info; */
|
||||
/* OBSOLETE void a29k_get_saved_register (char *raw_buffer, int *optimized, */
|
||||
/* OBSOLETE CORE_ADDR * addrp, struct frame_info *frame, */
|
||||
/* OBSOLETE int regnum, enum lval_type *lvalp); */
|
||||
/* OBSOLETE #define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \ */
|
||||
/* OBSOLETE a29k_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Call function stuff. */ */
|
||||
/* OBSOLETE /* *INDENT-OFF* */ */
|
||||
/* OBSOLETE /* The dummy frame looks like this (see also the general frame picture */
|
||||
/* OBSOLETE above): */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE register stack */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE | | frame for function */
|
||||
/* OBSOLETE | locals_sproc | executing at time */
|
||||
/* OBSOLETE |________________| of call_function. */
|
||||
/* OBSOLETE | | We must not disturb */
|
||||
/* OBSOLETE | args_out_sproc | it. */
|
||||
/* OBSOLETE memory stack |________________| */
|
||||
/* OBSOLETE |____lr1_sproc___|<-+ */
|
||||
/* OBSOLETE | | |__retaddr_sproc_| | <-- gr1 (at start) */
|
||||
/* OBSOLETE |____________|<-msp 0 <-----------mfp_dummy_____| | */
|
||||
/* OBSOLETE | | (at start) | save regs | | */
|
||||
/* OBSOLETE | arg_slop | | pc0,pc1 | | */
|
||||
/* OBSOLETE | | | pc2,lr0 sproc | | */
|
||||
/* OBSOLETE | (16 words) | | gr96-gr124 | | */
|
||||
/* OBSOLETE |____________|<-msp 1--after | sr160-sr162 | | */
|
||||
/* OBSOLETE | | PUSH_DUMMY_FRAME| sr128-sr135 | | */
|
||||
/* OBSOLETE | struct ret | |________________| | */
|
||||
/* OBSOLETE | 17+ | | | | */
|
||||
/* OBSOLETE |____________|<- lrp | args_out_dummy | | */
|
||||
/* OBSOLETE | struct ret | | (16 words) | | */
|
||||
/* OBSOLETE | 16 | |________________| | */
|
||||
/* OBSOLETE | (16 words) | |____lr1_dummy___|--+ */
|
||||
/* OBSOLETE |____________|<- msp 2--after |_retaddr_dummy__|<- gr1 after */
|
||||
/* OBSOLETE | | struct ret | | PUSH_DUMMY_FRAME */
|
||||
/* OBSOLETE | margs17+ | area allocated | locals_inf | */
|
||||
/* OBSOLETE | | |________________| called */
|
||||
/* OBSOLETE |____________|<- msp 4--when | | function's */
|
||||
/* OBSOLETE | | inf called | args_out_inf | frame (set up */
|
||||
/* OBSOLETE | margs16 | |________________| by called */
|
||||
/* OBSOLETE | (16 words) | |_____lr1_inf____| function). */
|
||||
/* OBSOLETE |____________|<- msp 3--after | . | */
|
||||
/* OBSOLETE | | args pushed | . | */
|
||||
/* OBSOLETE | | | . | */
|
||||
/* OBSOLETE | | */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE arg_slop: This area is so that when the call dummy adds 16 words to */
|
||||
/* OBSOLETE the msp, it won't end up larger than mfp_dummy (it is needed in the */
|
||||
/* OBSOLETE case where margs and struct_ret do not add up to at least 16 words). */
|
||||
/* OBSOLETE struct ret: This area is allocated by GDB if the return value is more */
|
||||
/* OBSOLETE than 16 words. struct ret_16 is not used on the a29k. */
|
||||
/* OBSOLETE margs: Pushed by GDB. The call dummy copies the first 16 words to */
|
||||
/* OBSOLETE args_out_dummy. */
|
||||
/* OBSOLETE retaddr_sproc: Contains the PC at the time we call the function. */
|
||||
/* OBSOLETE set by PUSH_DUMMY_FRAME and read by POP_FRAME. */
|
||||
/* OBSOLETE retaddr_dummy: This points to a breakpoint instruction in the dummy. */ */
|
||||
/* OBSOLETE /* *INDENT-ON* */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Rsize for dummy frame, in bytes. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Bytes for outgoing args, lr1, and retaddr. */ */
|
||||
/* OBSOLETE #define DUMMY_ARG (2 * 4 + 16 * 4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Number of special registers (sr128-) to save. */ */
|
||||
/* OBSOLETE #define DUMMY_SAVE_SR128 8 */
|
||||
/* OBSOLETE /* Number of special registers (sr160-) to save. */ */
|
||||
/* OBSOLETE #define DUMMY_SAVE_SR160 3 */
|
||||
/* OBSOLETE /* Number of general (gr96- or gr64-) registers to save. */ */
|
||||
/* OBSOLETE #define DUMMY_SAVE_GREGS 29 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define DUMMY_FRAME_RSIZE \ */
|
||||
/* OBSOLETE (4 /* mfp_dummy */ \ */
|
||||
/* OBSOLETE + 4 * 4 /* pc0, pc1, pc2, lr0 */ \ */
|
||||
/* OBSOLETE + DUMMY_SAVE_GREGS * 4 \ */
|
||||
/* OBSOLETE + DUMMY_SAVE_SR160 * 4 \ */
|
||||
/* OBSOLETE + DUMMY_SAVE_SR128 * 4 \ */
|
||||
/* OBSOLETE + DUMMY_ARG \ */
|
||||
/* OBSOLETE + 4 /* pad to doubleword */ ) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Push an empty stack frame, to record the current PC, etc. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define PUSH_DUMMY_FRAME push_dummy_frame() */
|
||||
/* OBSOLETE extern void push_dummy_frame (); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Discard from the stack the innermost frame, */
|
||||
/* OBSOLETE restoring all saved registers. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define POP_FRAME pop_frame() */
|
||||
/* OBSOLETE extern void pop_frame (); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* This sequence of words is the instructions */
|
||||
/* OBSOLETE mtsrim cr, 15 */
|
||||
/* OBSOLETE loadm 0, 0, lr2, msp ; load first 16 words of arguments into registers */
|
||||
/* OBSOLETE add msp, msp, 16 * 4 ; point to the remaining arguments */
|
||||
/* OBSOLETE CONST_INSN: */
|
||||
/* OBSOLETE const lr0,inf ; (replaced by half of target addr) */
|
||||
/* OBSOLETE consth lr0,inf ; (replaced by other half of target addr) */
|
||||
/* OBSOLETE calli lr0, lr0 */
|
||||
/* OBSOLETE aseq 0x40,gr1,gr1 ; nop */
|
||||
/* OBSOLETE BREAKPT_INSN: */
|
||||
/* OBSOLETE asneq 0x50,gr1,gr1 ; breakpoint (replaced by local breakpoint insn) */
|
||||
/* OBSOLETE */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #error "This file is broken. GDB does not define HOST_BYTE_ORDER." */
|
||||
/* OBSOLETE #if TARGET_BYTE_ORDER == HOST_BYTE_ORDER */
|
||||
/* OBSOLETE #define BS(const) const */
|
||||
/* OBSOLETE #else */
|
||||
/* OBSOLETE #define BS(const) (((const) & 0xff) << 24) | \ */
|
||||
/* OBSOLETE (((const) & 0xff00) << 8) | \ */
|
||||
/* OBSOLETE (((const) & 0xff0000) >> 8) | \ */
|
||||
/* OBSOLETE (((const) & 0xff000000) >> 24) */
|
||||
/* OBSOLETE #endif */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Position of the "const" and blkt instructions within CALL_DUMMY in bytes. */ */
|
||||
/* OBSOLETE #define CONST_INSN (3 * 4) */
|
||||
/* OBSOLETE #define BREAKPT_INSN (7 * 4) */
|
||||
/* OBSOLETE #define CALL_DUMMY { \ */
|
||||
/* OBSOLETE BS(0x0400870f),\ */
|
||||
/* OBSOLETE BS(0x36008200|(MSP_HW_REGNUM)), \ */
|
||||
/* OBSOLETE BS(0x15000040|(MSP_HW_REGNUM<<8)|(MSP_HW_REGNUM<<16)), \ */
|
||||
/* OBSOLETE BS(0x03ff80ff), \ */
|
||||
/* OBSOLETE BS(0x02ff80ff), \ */
|
||||
/* OBSOLETE BS(0xc8008080), \ */
|
||||
/* OBSOLETE BS(0x70400101), \ */
|
||||
/* OBSOLETE BS(0x72500101)} */
|
||||
/* OBSOLETE #define CALL_DUMMY_LENGTH (8 * 4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define CALL_DUMMY_START_OFFSET 0 /* Start execution at beginning of dummy */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Helper macro for FIX_CALL_DUMMY. WORDP is a long * which points to a */
|
||||
/* OBSOLETE word in target byte order; bits 0-7 and 16-23 of *WORDP are replaced with */
|
||||
/* OBSOLETE bits 0-7 and 8-15 of DATA (which is in host byte order). */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #if TARGET_BYTE_ORDER == BFD_ENDIAN_BIG */
|
||||
/* OBSOLETE #define STUFF_I16(WORDP, DATA) \ */
|
||||
/* OBSOLETE { \ */
|
||||
/* OBSOLETE *((char *)(WORDP) + 3) = ((DATA) & 0xff);\ */
|
||||
/* OBSOLETE *((char *)(WORDP) + 1) = (((DATA) >> 8) & 0xff);\ */
|
||||
/* OBSOLETE } */
|
||||
/* OBSOLETE #else /* Target is little endian. */ */
|
||||
/* OBSOLETE #define STUFF_I16(WORDP, DATA) \ */
|
||||
/* OBSOLETE { */
|
||||
/* OBSOLETE *(char *) (WORDP) = ((DATA) & 0xff); */
|
||||
/* OBSOLETE *((char *) (WORDP) + 2) = (((DATA) >> 8) & 0xff); */
|
||||
/* OBSOLETE } */
|
||||
/* OBSOLETE #endif /* Target is little endian. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Insert the specified number of args and function address */
|
||||
/* OBSOLETE into a call sequence of the above form stored at DUMMYNAME. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Currently this stuffs in the address of the function that we are calling. */
|
||||
/* OBSOLETE Since different a29k systems use different breakpoint instructions, it */
|
||||
/* OBSOLETE also stuffs BREAKPOINT in the right place (to avoid having to */
|
||||
/* OBSOLETE duplicate CALL_DUMMY in each tm-*.h file). */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \ */
|
||||
/* OBSOLETE {\ */
|
||||
/* OBSOLETE STUFF_I16((char *)dummyname + CONST_INSN, fun); \ */
|
||||
/* OBSOLETE STUFF_I16((char *)dummyname + CONST_INSN + 4, fun >> 16); \ */
|
||||
/* OBSOLETE /* FIXME memcpy ((char *)(dummyname) + BREAKPT_INSN, break_insn, 4); */ \ */
|
||||
/* OBSOLETE } */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* a29k architecture has separate data & instruction memories -- wired to */
|
||||
/* OBSOLETE different pins on the chip -- and can't execute the data memory. */
|
||||
/* OBSOLETE Also, there should be space after text_end; */
|
||||
/* OBSOLETE we won't get a SIGSEGV or scribble on data space. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define CALL_DUMMY_LOCATION AFTER_TEXT_END */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Because of this, we need (as a kludge) to know the addresses of the */
|
||||
/* OBSOLETE text section. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define NEED_TEXT_START_END 1 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* How to translate register numbers in the .stab's into gdb's internal register */
|
||||
/* OBSOLETE numbers. We don't translate them, but we warn if an invalid register */
|
||||
/* OBSOLETE number is seen. Note that FIXME, we use the value "sym" as an implicit */
|
||||
/* OBSOLETE argument in printing the error message. It happens to be available where */
|
||||
/* OBSOLETE this macro is used. (This macro definition appeared in a late revision */
|
||||
/* OBSOLETE of gdb-3.91.6 and is not well tested. Also, it should be a "complaint".) */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define STAB_REG_TO_REGNUM(num) \ */
|
||||
/* OBSOLETE (((num) > LR0_REGNUM + 127) \ */
|
||||
/* OBSOLETE ? fprintf(stderr, \ */
|
||||
/* OBSOLETE "Invalid register number %d in symbol table entry for %s\n", \ */
|
||||
/* OBSOLETE (num), SYMBOL_SOURCE_NAME (sym)), (num) \ */
|
||||
/* OBSOLETE : (num)) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE extern enum a29k_processor_types */
|
||||
/* OBSOLETE { */
|
||||
/* OBSOLETE a29k_unknown, */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Bit 0x400 of the CPS does *not* identify freeze mode, i.e. 29000, */
|
||||
/* OBSOLETE 29030, etc. */ */
|
||||
/* OBSOLETE a29k_no_freeze_mode, */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Bit 0x400 of the CPS does identify freeze mode, i.e. 29050. */ */
|
||||
/* OBSOLETE a29k_freeze_mode */
|
||||
/* OBSOLETE } */
|
||||
/* OBSOLETE processor_type; */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* We need three arguments for a general frame specification for the */
|
||||
/* OBSOLETE "frame" or "info frame" command. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv) */
|
||||
/* OBSOLETE extern struct frame_info *setup_arbitrary_frame (int, CORE_ADDR *); */
|
||||
@@ -1,230 +0,0 @@
|
||||
/* OBSOLETE /* Target machine description for VxWorks on the 29k, for GDB, the GNU debugger. */
|
||||
/* OBSOLETE Copyright 1994, 1995, 1998, 1999, 2000 Free Software Foundation, Inc. */
|
||||
/* OBSOLETE Contributed by Cygnus Support. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE This file is part of GDB. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE This program is free software; you can redistribute it and/or modify */
|
||||
/* OBSOLETE it under the terms of the GNU General Public License as published by */
|
||||
/* OBSOLETE the Free Software Foundation; either version 2 of the License, or */
|
||||
/* OBSOLETE (at your option) any later version. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE This program is distributed in the hope that it will be useful, */
|
||||
/* OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* OBSOLETE GNU General Public License for more details. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE You should have received a copy of the GNU General Public License */
|
||||
/* OBSOLETE along with this program; if not, write to the Free Software */
|
||||
/* OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, */
|
||||
/* OBSOLETE Boston, MA 02111-1307, USA. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #include "regcache.h" */
|
||||
/* OBSOLETE #include "value.h" */
|
||||
/* OBSOLETE #include "a29k/tm-a29k.h" */
|
||||
/* OBSOLETE #include "tm-vxworks.h" */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Number of registers in a ptrace_getregs call. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define VX_NUM_REGS (NUM_REGS) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Number of registers in a ptrace_getfpregs call. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* #define VX_SIZE_FPREGS */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* This is almost certainly the wrong place for this: */ */
|
||||
/* OBSOLETE #define LR2_REGNUM 34 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Vxworks has its own CALL_DUMMY since it manages breakpoints in the kernel */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #undef CALL_DUMMY */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Replace the breakpoint instruction in the CALL_DUMMY with a nop. */
|
||||
/* OBSOLETE For Vxworks, the breakpoint is set and deleted by calls to */
|
||||
/* OBSOLETE CALL_DUMMY_BREAK_SET and CALL_DUMMY_BREAK_DELETE. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #error "This file is broken. GDB does not define HOST_BYTE_ORDER." */
|
||||
/* OBSOLETE #if TARGET_BYTE_ORDER == HOST_BYTE_ORDER */
|
||||
/* OBSOLETE #define CALL_DUMMY {0x0400870f,\ */
|
||||
/* OBSOLETE 0x36008200|(MSP_HW_REGNUM), \ */
|
||||
/* OBSOLETE 0x15000040|(MSP_HW_REGNUM<<8)|(MSP_HW_REGNUM<<16), \ */
|
||||
/* OBSOLETE 0x03ff80ff, 0x02ff80ff, 0xc8008080, 0x70400101, 0x70400101} */
|
||||
/* OBSOLETE #else /* Byte order differs. */ */
|
||||
/* OBSOLETE #define CALL_DUMMY {0x0f870004,\ */
|
||||
/* OBSOLETE 0x00820036|(MSP_HW_REGNUM << 24), \ */
|
||||
/* OBSOLETE 0x40000015|(MSP_HW_REGNUM<<8)|(MSP_HW_REGNUM<<16), \ */
|
||||
/* OBSOLETE 0xff80ff03, 0xff80ff02, 0x808000c8, 0x01014070, 0x01014070} */
|
||||
/* OBSOLETE #endif /* Byte order differs. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* For the basic CALL_DUMMY definitions, see "tm-29k.h." We use the */
|
||||
/* OBSOLETE same CALL_DUMMY code, but define FIX_CALL_DUMMY (and related macros) */
|
||||
/* OBSOLETE locally to handle remote debugging of VxWorks targets. The difference */
|
||||
/* OBSOLETE is in the setting and clearing of the breakpoint at the end of the */
|
||||
/* OBSOLETE CALL_DUMMY code fragment; under VxWorks, we can't simply insert a */
|
||||
/* OBSOLETE breakpoint instruction into the code, since that would interfere with */
|
||||
/* OBSOLETE the breakpoint management mechanism on the target. */
|
||||
/* OBSOLETE Note that CALL_DUMMY is a piece of code that is used to call any C function */
|
||||
/* OBSOLETE thru VxGDB */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* The offset of the instruction within the CALL_DUMMY code where we */
|
||||
/* OBSOLETE want the inferior to stop after the function call has completed. */
|
||||
/* OBSOLETE call_function_by_hand () sets a breakpoint here (via CALL_DUMMY_BREAK_SET), */
|
||||
/* OBSOLETE which POP_FRAME later deletes (via CALL_DUMMY_BREAK_DELETE). */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define CALL_DUMMY_STOP_OFFSET (7 * 4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* The offset of the first instruction of the CALL_DUMMY code fragment */
|
||||
/* OBSOLETE relative to the frame pointer for a dummy frame. This is equal to */
|
||||
/* OBSOLETE the size of the CALL_DUMMY plus the arg_slop area size (see the diagram */
|
||||
/* OBSOLETE in "tm-29k.h"). */ */
|
||||
/* OBSOLETE /* PAD : the arg_slop area size doesn't appear to me to be useful since, the */
|
||||
/* OBSOLETE call dummy code no longer modify the msp. See below. This must be checked. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define CALL_DUMMY_OFFSET_IN_FRAME (CALL_DUMMY_LENGTH + 16 * 4) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Insert the specified number of args and function address */
|
||||
/* OBSOLETE into a CALL_DUMMY sequence stored at DUMMYNAME, replace the third */
|
||||
/* OBSOLETE instruction (add msp, msp, 16*4) with a nop, and leave the final nop. */
|
||||
/* OBSOLETE We can't keep using a CALL_DUMMY that modify the msp since, for VxWorks, */
|
||||
/* OBSOLETE CALL_DUMMY is stored in the Memory Stack. Adding 16 words to the msp */
|
||||
/* OBSOLETE would then make possible for the inferior to overwrite the CALL_DUMMY code, */
|
||||
/* OBSOLETE thus creating a lot of trouble when exiting the inferior to come back in */
|
||||
/* OBSOLETE a CALL_DUMMY code that no longer exists... Furthermore, ESF are also stored */
|
||||
/* OBSOLETE from the msp in the memory stack. If msp is set higher than the dummy code, */
|
||||
/* OBSOLETE an ESF may clobber this code. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #if TARGET_BYTE_ORDER == BFD_ENDIAN_BIG */
|
||||
/* OBSOLETE #define NOP_INSTR 0x70400101 */
|
||||
/* OBSOLETE #else /* Target is little endian */ */
|
||||
/* OBSOLETE #define NOP_INSTR 0x01014070 */
|
||||
/* OBSOLETE #endif */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #undef FIX_CALL_DUMMY */
|
||||
/* OBSOLETE #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \ */
|
||||
/* OBSOLETE { \ */
|
||||
/* OBSOLETE *(int *)((char *)dummyname + 8) = NOP_INSTR; \ */
|
||||
/* OBSOLETE STUFF_I16((char *)dummyname + CONST_INSN, fun); \ */
|
||||
/* OBSOLETE STUFF_I16((char *)dummyname + CONST_INSN + 4, fun >> 16); \ */
|
||||
/* OBSOLETE } */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* For VxWorks, CALL_DUMMY must be stored in the stack of the task that is */
|
||||
/* OBSOLETE being debugged and executed "in the context of" this task */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #undef CALL_DUMMY_LOCATION */
|
||||
/* OBSOLETE #define CALL_DUMMY_LOCATION ON_STACK */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Set or delete a breakpoint at the location within a CALL_DUMMY code */
|
||||
/* OBSOLETE fragment where we want the target program to stop after the function */
|
||||
/* OBSOLETE call is complete. CALL_DUMMY_ADDR is the address of the first */
|
||||
/* OBSOLETE instruction in the CALL_DUMMY. DUMMY_FRAME_ADDR is the value of the */
|
||||
/* OBSOLETE frame pointer in the dummy frame. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE NOTE: in the both of the following definitions, we take advantage of */
|
||||
/* OBSOLETE knowledge of the implementation of the target breakpoint operation, */
|
||||
/* OBSOLETE in that we pass a null pointer as the second argument. It seems */
|
||||
/* OBSOLETE reasonable to assume that any target requiring the use of */
|
||||
/* OBSOLETE CALL_DUMMY_BREAK_{SET,DELETE} will not store the breakpoint */
|
||||
/* OBSOLETE shadow contents in GDB; in any case, this assumption is vaild */
|
||||
/* OBSOLETE for all VxWorks-related targets. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define CALL_DUMMY_BREAK_SET(call_dummy_addr) \ */
|
||||
/* OBSOLETE target_insert_breakpoint ((call_dummy_addr) + CALL_DUMMY_STOP_OFFSET, \ */
|
||||
/* OBSOLETE (char *) 0) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define CALL_DUMMY_BREAK_DELETE(dummy_frame_addr) \ */
|
||||
/* OBSOLETE target_remove_breakpoint ((dummy_frame_addr) - (CALL_DUMMY_OFFSET_IN_FRAME \ */
|
||||
/* OBSOLETE - CALL_DUMMY_STOP_OFFSET), \ */
|
||||
/* OBSOLETE (char *) 0) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Return nonzero if the pc is executing within a CALL_DUMMY frame. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define PC_IN_CALL_DUMMY(pc, sp, frame_address) \ */
|
||||
/* OBSOLETE ((pc) >= (sp) \ */
|
||||
/* OBSOLETE && (pc) <= (sp) + CALL_DUMMY_OFFSET_IN_FRAME + CALL_DUMMY_LENGTH) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Defining this prevents us from trying to pass a structure-valued argument */
|
||||
/* OBSOLETE to a function called via the CALL_DUMMY mechanism. This is not handled */
|
||||
/* OBSOLETE properly in call_function_by_hand (), and the fix might require re-writing */
|
||||
/* OBSOLETE the CALL_DUMMY handling for all targets (at least, a clean solution */
|
||||
/* OBSOLETE would probably require this). Arguably, this should go in "tm-29k.h" */
|
||||
/* OBSOLETE rather than here. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define STRUCT_VAL_ARGS_UNSUPPORTED */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define BKPT_OFFSET (7 * 4) */
|
||||
/* OBSOLETE #define BKPT_INSTR 0x72500101 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #undef FIX_CALL_DUMMY */
|
||||
/* OBSOLETE #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \ */
|
||||
/* OBSOLETE {\ */
|
||||
/* OBSOLETE STUFF_I16((char *)dummyname + CONST_INSN, fun);\ */
|
||||
/* OBSOLETE STUFF_I16((char *)dummyname + CONST_INSN + 4, fun >> 16);\ */
|
||||
/* OBSOLETE *(int *)((char *)dummyname + BKPT_OFFSET) = BKPT_INSTR;\ */
|
||||
/* OBSOLETE } */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Offsets into jmp_buf. They are derived from VxWorks' REG_SET struct */
|
||||
/* OBSOLETE (see VxWorks' setjmp.h). Note that Sun2, Sun3 and SunOS4 and VxWorks have */
|
||||
/* OBSOLETE different REG_SET structs, hence different layouts for the jmp_buf struct. */
|
||||
/* OBSOLETE Only JB_PC is needed for getting the saved PC value. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define JB_ELEMENT_SIZE 4 /* size of each element in jmp_buf */ */
|
||||
/* OBSOLETE #define JB_PC 3 /* offset of pc (pc1) in jmp_buf */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Figure out where the longjmp will land. We expect that we have just entered */
|
||||
/* OBSOLETE longjmp and haven't yet setup the stack frame, so the args are still in the */
|
||||
/* OBSOLETE output regs. lr2 (LR2_REGNUM) points at the jmp_buf structure from which we */
|
||||
/* OBSOLETE extract the pc (JB_PC) that we will land at. The pc is copied into ADDR. */
|
||||
/* OBSOLETE This routine returns true on success */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR) */
|
||||
/* OBSOLETE extern int get_longjmp_target (CORE_ADDR *); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* VxWorks adjusts the PC after a breakpoint has been hit. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #undef DECR_PC_AFTER_BREAK */
|
||||
/* OBSOLETE #define DECR_PC_AFTER_BREAK 0 */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE /* Do whatever promotions are appropriate on a value being returned */
|
||||
/* OBSOLETE from a function. VAL is the user-supplied value, and FUNC_TYPE */
|
||||
/* OBSOLETE is the return type of the function if known, else 0. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE For the Am29k, as far as I understand, if the function return type is known, */
|
||||
/* OBSOLETE cast the value to that type; otherwise, ensure that integer return values */
|
||||
/* OBSOLETE fill all of gr96. */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE This definition really belongs in "tm-29k.h", since it applies */
|
||||
/* OBSOLETE to most Am29K-based systems; but once moved into that file, it might */
|
||||
/* OBSOLETE need to be redefined for all Am29K-based targets that also redefine */
|
||||
/* OBSOLETE STORE_RETURN_VALUE. For now, to be safe, we define it here. */ */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #define PROMOTE_RETURN_VALUE(val, func_type) \ */
|
||||
/* OBSOLETE do { \ */
|
||||
/* OBSOLETE if (func_type) \ */
|
||||
/* OBSOLETE val = value_cast (func_type, val); \ */
|
||||
/* OBSOLETE if ((TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT \ */
|
||||
/* OBSOLETE || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ENUM) \ */
|
||||
/* OBSOLETE && TYPE_LENGTH (VALUE_TYPE (val)) < REGISTER_RAW_SIZE (0)) \ */
|
||||
/* OBSOLETE val = value_cast (builtin_type_int, val); \ */
|
||||
/* OBSOLETE } while (0) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE extern int vx29k_frame_chain_valid (CORE_ADDR, struct frame_info *); */
|
||||
/* OBSOLETE #define FRAME_CHAIN_VALID(chain, thisframe) vx29k_frame_chain_valid (chain, thisframe) */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE extern CORE_ADDR frame_saved_call_site (); */
|
||||
/* OBSOLETE */
|
||||
/* OBSOLETE #undef PREPARE_TO_INIT_FRAME_INFO */
|
||||
/* OBSOLETE #define PREPARE_TO_INIT_FRAME_INFO(fci) do { \ */
|
||||
/* OBSOLETE long current_msp = read_register (MSP_REGNUM); \ */
|
||||
/* OBSOLETE if (PC_IN_CALL_DUMMY (fci->pc, current_msp, 0)) \ */
|
||||
/* OBSOLETE { \ */
|
||||
/* OBSOLETE fci->rsize = DUMMY_FRAME_RSIZE; \ */
|
||||
/* OBSOLETE fci->msize = 0; \ */
|
||||
/* OBSOLETE fci->saved_msp = \ */
|
||||
/* OBSOLETE read_register_stack_integer (fci->frame + DUMMY_FRAME_RSIZE - 4, 4); \ */
|
||||
/* OBSOLETE fci->flags |= (TRANSPARENT|MFP_USED); \ */
|
||||
/* OBSOLETE return; \ */
|
||||
/* OBSOLETE } \ */
|
||||
/* OBSOLETE } while (0) */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user