More changes, mostly from IBM for rs6000. (See ChangeLog.)
This commit is contained in:
parent
4b8333deca
commit
6c6afbb92b
@ -1,3 +1,49 @@
|
||||
Sun Mar 1 17:41:09 1992 Per Bothner (bothner@cygnus.com)
|
||||
|
||||
* breakpoint.c (breakpoint_re_set): Removed (at least for now)
|
||||
printing of blank line, since it cases printing of an
|
||||
extra blank line. Is this intended? It does mess up
|
||||
gdb test suite.
|
||||
* defs.h: Put back declarations of malloc and realloc,
|
||||
but protected by #ifndef MALLOC_INCOMPATIBLE.
|
||||
* objfiles.c: Undo previous change: Use malloc/realloc
|
||||
for objfile malloc/realloc fields (but add a cast).
|
||||
* xcoffexec.c: Suppress an error message (for now).
|
||||
|
||||
Sat Feb 29 14:43:02 1992 Per Bothner (bothner@cygnus.com)
|
||||
|
||||
Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
|
||||
[Mail dated Fri, 21 Feb 92 13:14:54 -0800]
|
||||
* buildsym.c: Use smash_to_pointer_type() to handle forward type
|
||||
references.
|
||||
* xcoffread.c: Modifications to C_DECL storage class handling, and
|
||||
introduction of an old smash_to_pointer_type() routine.
|
||||
|
||||
Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
|
||||
[Mail dated Thu, 20 Feb 92 13:57:16 -0800]
|
||||
* rs6000-xdep.c, rs6000-tdep.c, tm-rs6000.h: function_frame_info()
|
||||
parameters have been modified.
|
||||
|
||||
Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
|
||||
[Mail dated Thu, 20 Feb 92 10:10:05 -0800]
|
||||
* rs6000-tdep.c: Before Feb 5 92, register_valid[] array was not used,
|
||||
and fetch_inferior_registers() always fetched all the registers
|
||||
resulting valid register values at hand all the time. Pushing a dummy
|
||||
frame did not require validating all register values first. After
|
||||
putting the above mechanism into action, we didn't have valid registers
|
||||
values always ready. Thus, all registers need to be fetched before
|
||||
pushing a dummy frame now.
|
||||
|
||||
Changes from metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik)
|
||||
[Mail dated Thu, 13 Feb 92 16:22:44 -0800]
|
||||
* rs6000-xdep.c: frame_initial_stack_address() function to calculate
|
||||
the starting address (actual frame address) of a frame.
|
||||
* rs6000-tdep.c: modifications to function_frame_info() to see if
|
||||
function reserves a frame pointer register (alloca register)
|
||||
* tm-rs6000.h: EXTRA_FRAME_INFO, FRAME_ARGS_ADDRESS and
|
||||
FRAME_LOCALS_ADDRESS has been updated to support debugging of
|
||||
functions with alloca() calls.
|
||||
|
||||
Sun Mar 1 13:13:39 1992 Fred Fish (fnf@cygnus.com)
|
||||
|
||||
* xm-sysv4.h: Provide definitions/prototypes for host environment
|
||||
|
@ -726,7 +726,9 @@ patch_block_stabs (symbols, stabs, objfile)
|
||||
struct symbol *sym = find_symbol_in_list (symbols, name, pp-name);
|
||||
if (!sym)
|
||||
{
|
||||
#ifndef IBM6000
|
||||
printf ("ERROR! stab symbol not found!\n"); /* FIXME */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -64,8 +64,8 @@ allocate_objfile (abfd, filename, dumpable)
|
||||
{
|
||||
objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
|
||||
(void) memset (objfile, 0, sizeof (struct objfile));
|
||||
objfile -> malloc = xmalloc;
|
||||
objfile -> realloc = xrealloc;
|
||||
objfile -> malloc = (PTR (*) PARAMS ((long))) malloc;
|
||||
objfile -> realloc = (PTR (*) PARAMS ((PTR, long))) realloc;
|
||||
objfile -> xmalloc = xmalloc;
|
||||
objfile -> xrealloc = xrealloc;
|
||||
objfile -> free = free;
|
||||
|
@ -246,7 +246,6 @@ int pc;
|
||||
CORE_ADDR text_start;
|
||||
CORE_ADDR text_end;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Support for creating pushind a dummy frame into the stack, and popping
|
||||
frames, etc.
|
||||
@ -282,6 +281,8 @@ push_dummy_frame ()
|
||||
int sp, pc; /* stack pointer and link register */
|
||||
int ii;
|
||||
|
||||
fetch_inferior_registers (-1);
|
||||
|
||||
if (dummy_frame_count >= dummy_frame_size) {
|
||||
dummy_frame_size += DUMMY_FRAME_ADDR_SIZE;
|
||||
if (dummy_frame_addr)
|
||||
@ -298,7 +299,7 @@ push_dummy_frame ()
|
||||
dummy_frame_addr [dummy_frame_count++] = sp;
|
||||
|
||||
/* Be careful! If the stack pointer is not decremented first, then kernel
|
||||
thinks he is free to use the sapce underneath it. And kernel actually
|
||||
thinks he is free to use the space underneath it. And kernel actually
|
||||
uses that area for IPC purposes when executing ptrace(2) calls. So
|
||||
before writing register values into the new frame, decrement and update
|
||||
%sp first in order to secure your frame. */
|
||||
@ -314,8 +315,7 @@ push_dummy_frame ()
|
||||
/* save program counter in link register's space. */
|
||||
write_memory (sp+8, &pc, 4);
|
||||
|
||||
/* save full floating point registers here. They will be from F14..F31
|
||||
for know. I am not sure if we need to save everything here! */
|
||||
/* save all floating point and general purpose registers here. */
|
||||
|
||||
/* fpr's, f0..f31 */
|
||||
for (ii = 0; ii < 32; ++ii)
|
||||
@ -399,11 +399,9 @@ pop_dummy_frame ()
|
||||
pop_frame ()
|
||||
{
|
||||
int pc, lr, sp, prev_sp; /* %pc, %lr, %sp */
|
||||
struct aix_framedata fdata;
|
||||
FRAME fr = get_current_frame ();
|
||||
int offset = 0;
|
||||
int frameless = 0; /* TRUE if function is frameless */
|
||||
int addr, ii;
|
||||
int saved_gpr, saved_fpr; /* # of saved gpr's and fpr's */
|
||||
|
||||
pc = read_pc ();
|
||||
sp = FRAME_FP (fr);
|
||||
@ -418,10 +416,10 @@ pop_frame ()
|
||||
saved %pc value in the previous frame. */
|
||||
|
||||
addr = get_pc_function_start (fr->pc) + FUNCTION_START_OFFSET;
|
||||
function_frame_info (addr, &frameless, &offset, &saved_gpr, &saved_fpr);
|
||||
function_frame_info (addr, &fdata);
|
||||
|
||||
read_memory (sp, &prev_sp, 4);
|
||||
if (frameless)
|
||||
if (fdata.frameless)
|
||||
lr = read_register (LR_REGNUM);
|
||||
else
|
||||
read_memory (prev_sp+8, &lr, 4);
|
||||
@ -430,16 +428,16 @@ pop_frame ()
|
||||
write_register (PC_REGNUM, lr);
|
||||
|
||||
/* reset register values if any was saved earlier. */
|
||||
addr = prev_sp - offset;
|
||||
addr = prev_sp - fdata.offset;
|
||||
|
||||
if (saved_gpr != -1)
|
||||
for (ii=saved_gpr; ii <= 31; ++ii) {
|
||||
if (fdata.saved_gpr != -1)
|
||||
for (ii=fdata.saved_gpr; ii <= 31; ++ii) {
|
||||
read_memory (addr, ®isters [REGISTER_BYTE (ii)], 4);
|
||||
addr += sizeof (int);
|
||||
}
|
||||
|
||||
if (saved_fpr != -1)
|
||||
for (ii=saved_fpr; ii <= 31; ++ii) {
|
||||
if (fdata.saved_fpr != -1)
|
||||
for (ii=fdata.saved_fpr; ii <= 31; ++ii) {
|
||||
read_memory (addr, ®isters [REGISTER_BYTE (ii+FP0_REGNUM)], 8);
|
||||
addr += 8;
|
||||
}
|
||||
@ -492,29 +490,32 @@ fix_call_dummy(dummyname, pc, fun, nargs, type)
|
||||
|
||||
|
||||
/* return information about a function frame.
|
||||
in struct aix_frameinfo fdata:
|
||||
- frameless is TRUE, if function does not save %pc value in its frame.
|
||||
- offset is the number of bytes used in the frame to save registers.
|
||||
- saved_gpr is the number of the first saved gpr.
|
||||
- saved_fpr is the number of the first saved fpr.
|
||||
- alloca_reg is the number of the register used for alloca() handling.
|
||||
Otherwise -1.
|
||||
*/
|
||||
function_frame_info (pc, frameless, offset, saved_gpr, saved_fpr)
|
||||
function_frame_info (pc, fdata)
|
||||
int pc;
|
||||
int *frameless, *offset, *saved_gpr, *saved_fpr;
|
||||
struct aix_framedata *fdata;
|
||||
{
|
||||
unsigned int tmp;
|
||||
register unsigned int op;
|
||||
|
||||
*offset = 0;
|
||||
*saved_gpr = *saved_fpr = -1;
|
||||
fdata->offset = 0;
|
||||
fdata->saved_gpr = fdata->saved_fpr = fdata->alloca_reg = -1;
|
||||
|
||||
op = read_memory_integer (pc, 4);
|
||||
if (op == 0x7c0802a6) { /* mflr r0 */
|
||||
pc += 4;
|
||||
op = read_memory_integer (pc, 4);
|
||||
*frameless = 0;
|
||||
fdata->frameless = 0;
|
||||
}
|
||||
else /* else, this is a frameless invocation */
|
||||
*frameless = 1;
|
||||
fdata->frameless = 1;
|
||||
|
||||
|
||||
if ((op & 0xfc00003e) == 0x7c000026) { /* mfcr Rx */
|
||||
@ -534,21 +535,60 @@ function_frame_info (pc, frameless, offset, saved_gpr, saved_fpr)
|
||||
|
||||
if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
|
||||
int tmp2;
|
||||
*saved_gpr = (op >> 21) & 0x1f;
|
||||
fdata->saved_gpr = (op >> 21) & 0x1f;
|
||||
tmp2 = op & 0xffff;
|
||||
if (tmp2 > 0x7fff)
|
||||
tmp2 = 0xffff0000 | tmp2;
|
||||
|
||||
if (tmp2 < 0) {
|
||||
tmp2 = tmp2 * -1;
|
||||
*saved_fpr = (tmp2 - ((32 - *saved_gpr) * 4)) / 8;
|
||||
if ( *saved_fpr > 0)
|
||||
*saved_fpr = 32 - *saved_fpr;
|
||||
fdata->saved_fpr = (tmp2 - ((32 - fdata->saved_gpr) * 4)) / 8;
|
||||
if ( fdata->saved_fpr > 0)
|
||||
fdata->saved_fpr = 32 - fdata->saved_fpr;
|
||||
else
|
||||
*saved_fpr = -1;
|
||||
fdata->saved_fpr = -1;
|
||||
}
|
||||
*offset = tmp2;
|
||||
fdata->offset = tmp2;
|
||||
pc += 4;
|
||||
op = read_memory_integer (pc, 4);
|
||||
}
|
||||
|
||||
while (((tmp = op >> 16) == 0x9001) || /* st r0, NUM(r1) */
|
||||
(tmp == 0x9421) || /* stu r1, NUM(r1) */
|
||||
(op == 0x93e1fffc)) /* st r31,-4(r1) */
|
||||
{
|
||||
/* gcc takes a short cut and uses this instruction to save r31 only. */
|
||||
|
||||
if (op == 0x93e1fffc) {
|
||||
if (fdata->offset)
|
||||
/* fatal ("Unrecognized prolog."); */
|
||||
printf ("Unrecognized prolog!\n");
|
||||
|
||||
fdata->saved_gpr = 31;
|
||||
fdata->offset = 4;
|
||||
}
|
||||
pc += 4;
|
||||
op = read_memory_integer (pc, 4);
|
||||
}
|
||||
|
||||
while ((tmp = (op >> 22)) == 0x20f) { /* l r31, ... or */
|
||||
pc += 4; /* l r30, ... */
|
||||
op = read_memory_integer (pc, 4);
|
||||
}
|
||||
|
||||
/* store parameters into stack */
|
||||
while(
|
||||
(op & 0xfc1f0000) == 0xd8010000 || /* stfd Rx,NUM(r1) */
|
||||
(op & 0xfc1f0000) == 0x90010000 || /* st r?, NUM(r1) */
|
||||
(op & 0xfc000000) == 0xfc000000 || /* frsp, fp?, .. */
|
||||
(op & 0xd0000000) == 0xd0000000) /* stfs, fp?, .. */
|
||||
{
|
||||
pc += 4; /* store fpr double */
|
||||
op = read_memory_integer (pc, 4);
|
||||
}
|
||||
|
||||
if (op == 0x603f0000) /* oril r31, r1, 0x0 */
|
||||
fdata->alloca_reg = 31;
|
||||
}
|
||||
|
||||
|
||||
@ -676,12 +716,6 @@ ran_out_of_registers_for_arguments:
|
||||
|
||||
write_register (SP_REGNUM, sp);
|
||||
|
||||
#if 0
|
||||
pc = read_pc ();
|
||||
flush_cached_frames ();
|
||||
set_current_frame (create_new_frame (sp, pc));
|
||||
#endif
|
||||
|
||||
/* if the last argument copied into the registers didn't fit there
|
||||
completely, push the rest of it into stack. */
|
||||
|
||||
@ -715,18 +749,10 @@ ran_out_of_registers_for_arguments:
|
||||
ii += ((len + 3) & -4) / 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
else
|
||||
/* Secure stack areas first, before doing anything else. */
|
||||
write_register (SP_REGNUM, sp);
|
||||
|
||||
#if 0
|
||||
pc = read_pc ();
|
||||
flush_cached_frames ();
|
||||
set_current_frame (create_new_frame (sp, pc));
|
||||
#endif
|
||||
}
|
||||
|
||||
saved_sp = dummy_frame_addr [dummy_frame_count - 1];
|
||||
read_memory (saved_sp, tmp_buffer, 24);
|
||||
write_memory (sp, tmp_buffer, 24);
|
||||
|
@ -227,7 +227,7 @@ frameless_function_invocation (fi)
|
||||
struct frame_info *fi;
|
||||
{
|
||||
CORE_ADDR func_start;
|
||||
int frameless, dummy;
|
||||
struct aix_framedata fdata;
|
||||
|
||||
func_start = get_pc_function_start (fi->pc) + FUNCTION_START_OFFSET;
|
||||
|
||||
@ -237,11 +237,110 @@ struct frame_info *fi;
|
||||
if (!func_start)
|
||||
return 0;
|
||||
|
||||
function_frame_info (func_start, &frameless, &dummy, &dummy, &dummy);
|
||||
return frameless;
|
||||
function_frame_info (func_start, &fdata);
|
||||
return fdata.frameless;
|
||||
}
|
||||
|
||||
|
||||
/* Return the address of a frame. This is the inital %sp value when the frame
|
||||
was first allocated. For functions calling alloca(), it might be saved in
|
||||
an alloca register. */
|
||||
|
||||
CORE_ADDR
|
||||
frame_initial_stack_address (fi)
|
||||
struct frame_info *fi;
|
||||
{
|
||||
CORE_ADDR frame_addr, tmpaddr;
|
||||
struct aix_framedata fdata;
|
||||
struct frame_info *callee_fi;
|
||||
int ii;
|
||||
|
||||
extern struct obstack frame_cache_obstack;
|
||||
|
||||
/* if the initial stack pointer (frame address) of this frame is known,
|
||||
just return it. */
|
||||
|
||||
if (fi->initial_sp)
|
||||
return fi->initial_sp;
|
||||
|
||||
/* find out if this function is using an alloca register.. */
|
||||
|
||||
tmpaddr = get_pc_function_start (fi->pc);
|
||||
function_frame_info (tmpaddr, &fdata);
|
||||
|
||||
/* if saved registers of this frame are not known yet, read and cache them. */
|
||||
|
||||
if (!fi->cache_fsr) {
|
||||
fi->cache_fsr = (struct frame_saved_regs *)
|
||||
obstack_alloc (&frame_cache_obstack, sizeof (struct frame_saved_regs));
|
||||
bzero (fi->cache_fsr, sizeof (struct frame_saved_regs));
|
||||
|
||||
if (fi->prev && fi->prev->frame)
|
||||
frame_addr = fi->prev->frame;
|
||||
else
|
||||
frame_addr = read_memory_integer (fi->frame, 4);
|
||||
|
||||
/* if != -1, fdata.saved_fpr is the smallest number of saved_fpr. All fpr's
|
||||
from saved_fpr to fp31 are saved right underneath caller stack pointer,
|
||||
starting from fp31 first. */
|
||||
|
||||
if (fdata.saved_fpr >= 0) {
|
||||
for (ii=31; ii >= fdata.saved_fpr; --ii)
|
||||
fi->cache_fsr->regs [FP0_REGNUM + ii] = frame_addr - ((32 - ii) * 8);
|
||||
frame_addr -= (32 - fdata.saved_fpr) * 8;
|
||||
}
|
||||
|
||||
/* if != -1, fdata.saved_gpr is the smallest number of saved_gpr. All gpr's
|
||||
from saved_gpr to gpr31 are saved right under saved fprs, starting
|
||||
from r31 first. */
|
||||
|
||||
if (fdata.saved_gpr >= 0)
|
||||
for (ii=31; ii >= fdata.saved_gpr; --ii)
|
||||
fi->cache_fsr->regs [ii] = frame_addr - ((32 - ii) * 4);
|
||||
}
|
||||
|
||||
/* If no alloca register used, then fi->frame is the value of the %sp for
|
||||
this frame, and it is good enough. */
|
||||
|
||||
if (fdata.alloca_reg < 0) {
|
||||
fi->initial_sp = fi->frame;
|
||||
return fi->initial_sp;
|
||||
}
|
||||
|
||||
/* This function has an alloca register. If this is the top-most frame
|
||||
(with the lowest address), the value in alloca register is good. */
|
||||
|
||||
if (!fi->next)
|
||||
return fi->initial_sp = read_register (fdata.alloca_reg);
|
||||
|
||||
/* Otherwise, this is a caller frame. Callee has already saved (???) its
|
||||
registers. Find the address in which caller's alloca register is saved. */
|
||||
|
||||
for (callee_fi = fi->next; callee_fi; callee_fi = callee_fi->next) {
|
||||
|
||||
if (!callee_fi->cache_fsr)
|
||||
fatal ("Callee has not saved caller's registers.");
|
||||
|
||||
/* this is the address in which alloca register is saved. */
|
||||
|
||||
tmpaddr = callee_fi->cache_fsr->regs [fdata.alloca_reg];
|
||||
if (tmpaddr) {
|
||||
fi->initial_sp = read_memory_integer (tmpaddr, 4);
|
||||
return fi->initial_sp;
|
||||
}
|
||||
|
||||
/* Go look into deeper levels of the frame chain to see if any one of
|
||||
the callees has saved alloca register. */
|
||||
}
|
||||
|
||||
/* If alloca register was not saved, by the callee (or any of its callees)
|
||||
then the value in the register is still good. */
|
||||
|
||||
return fi->initial_sp = read_register (fdata.alloca_reg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* aixcoff_relocate_symtab - hook for symbol table relocation.
|
||||
also reads shared libraries.. */
|
||||
|
||||
|
@ -72,15 +72,27 @@ extern char *corefile;
|
||||
/* We are missing register descriptions in the system header files. Sigh! */
|
||||
|
||||
struct regs {
|
||||
int gregs [32]; /* general purpose registers */
|
||||
int pc; /* program conter */
|
||||
int ps; /* processor status, or machine state */
|
||||
int gregs [32]; /* general purpose registers */
|
||||
int pc; /* program conter */
|
||||
int ps; /* processor status, or machine state */
|
||||
};
|
||||
|
||||
struct fp_status {
|
||||
double fpregs [32]; /* floating GP registers */
|
||||
double fpregs [32]; /* floating GP registers */
|
||||
};
|
||||
|
||||
|
||||
/* To be used by function_frame_info. */
|
||||
|
||||
struct aix_framedata {
|
||||
int offset; /* # of bytes in gpr's and fpr's are saved */
|
||||
int saved_gpr; /* smallest # of saved gpr */
|
||||
int saved_fpr; /* smallest # of saved fpr */
|
||||
int alloca_reg; /* alloca register number (frame ptr) */
|
||||
char frameless; /* true if frameless functions. */
|
||||
};
|
||||
|
||||
|
||||
/* Define the byte order of the machine. */
|
||||
|
||||
#define TARGET_BYTE_ORDER BIG_ENDIAN
|
||||
@ -418,12 +430,25 @@ extern unsigned int rs6000_struct_return_address;
|
||||
#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
|
||||
FRAMELESS = frameless_function_invocation (FI)
|
||||
|
||||
/* Functions calling alloca() change the value of the stack pointer. We
|
||||
need to use initial stack pointer (which is saved in r31 by gcc) in
|
||||
such cases. If a compiler emits traceback table, then we should use the
|
||||
alloca register specified in traceback table. FIXME. */
|
||||
/* Also, it is a good idea to cache information about frame's saved registers
|
||||
in the frame structure to speed things up. See tm-m88k.h. FIXME. */
|
||||
|
||||
#define EXTRA_FRAME_INFO \
|
||||
CORE_ADDR initial_sp; /* initial stack pointer. */ \
|
||||
struct frame_saved_regs *cache_fsr; /* saved registers */
|
||||
|
||||
/* Frameless function invocation in IBM RS/6000 is half-done. It perfectly
|
||||
sets up a new frame, e.g. a new frame (in fact stack) pointer, etc, but it
|
||||
doesn't save the %pc. In the following, even though it is considered a
|
||||
frameless invocation, we still need to walk one frame up. */
|
||||
|
||||
#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
|
||||
fi->initial_sp = 0; \
|
||||
fi->cache_fsr = 0; \
|
||||
if (fromleaf) { \
|
||||
int tmp = 0; \
|
||||
read_memory ((fi)->frame, &tmp, sizeof (int)); \
|
||||
@ -433,9 +458,13 @@ extern unsigned int rs6000_struct_return_address;
|
||||
#define FRAME_SAVED_PC(FRAME) \
|
||||
read_memory_integer (read_memory_integer ((FRAME)->frame, 4)+8, 4)
|
||||
|
||||
#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
|
||||
#define FRAME_ARGS_ADDRESS(FI) \
|
||||
(((struct frame_info*)(FI))->initial_sp ? \
|
||||
((struct frame_info*)(FI))->initial_sp : \
|
||||
frame_initial_stack_address (FI))
|
||||
|
||||
#define FRAME_LOCALS_ADDRESS(FI) FRAME_ARGS_ADDRESS(FI)
|
||||
|
||||
#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
|
||||
|
||||
/* Set VAL to the number of args passed to frame described by FI.
|
||||
Can set VAL to -1, meaning no way to tell. */
|
||||
@ -460,39 +489,42 @@ extern unsigned int rs6000_struct_return_address;
|
||||
|
||||
#define FRAME_FIND_SAVED_REGS(FRAME_INFO, FRAME_SAVED_REGS) \
|
||||
{ \
|
||||
int frameless, offset, saved_gpr, saved_fpr, ii, frame_addr, func_start; \
|
||||
int ii, frame_addr, func_start; \
|
||||
struct aix_framedata fdata; \
|
||||
\
|
||||
/* find the start of the function and collect info about its frame. */ \
|
||||
\
|
||||
func_start = get_pc_function_start ((FRAME_INFO)->pc) + FUNCTION_START_OFFSET;\
|
||||
function_frame_info (func_start, &frameless, &offset, &saved_gpr, &saved_fpr);\
|
||||
function_frame_info (func_start, &fdata); \
|
||||
bzero (&(FRAME_SAVED_REGS), sizeof (FRAME_SAVED_REGS)); \
|
||||
\
|
||||
/* if there were any saved registers, figure out parent's stack pointer. */ \
|
||||
frame_addr = 0; \
|
||||
if (saved_fpr >= 0 || saved_gpr >= 0) { \
|
||||
/* the following is true only if the frame doesn't have a call to alloca(), \
|
||||
FIXME. */ \
|
||||
if (fdata.saved_fpr >= 0 || fdata.saved_gpr >= 0) { \
|
||||
if ((FRAME_INFO)->prev && (FRAME_INFO)->prev->frame) \
|
||||
frame_addr = (FRAME_INFO)->prev->frame; \
|
||||
else \
|
||||
frame_addr = read_memory_integer ((FRAME_INFO)->frame, 4); \
|
||||
} \
|
||||
\
|
||||
/* if != -1, saved_fpr is the smallest number of saved_fpr. All fpr's \
|
||||
/* if != -1, fdata.saved_fpr is the smallest number of saved_fpr. All fpr's \
|
||||
from saved_fpr to fp31 are saved right underneath caller stack pointer, \
|
||||
starting from fp31 first. */ \
|
||||
\
|
||||
if (saved_fpr >= 0) { \
|
||||
for (ii=31; ii >= saved_fpr; --ii) \
|
||||
if (fdata.saved_fpr >= 0) { \
|
||||
for (ii=31; ii >= fdata.saved_fpr; --ii) \
|
||||
(FRAME_SAVED_REGS).regs [FP0_REGNUM + ii] = frame_addr - ((32 - ii) * 8); \
|
||||
frame_addr -= (32 - saved_fpr) * 8; \
|
||||
frame_addr -= (32 - fdata.saved_fpr) * 8; \
|
||||
} \
|
||||
\
|
||||
/* if != -1, saved_gpr is the smallest number of saved_gpr. All gpr's \
|
||||
/* if != -1, fdata.saved_gpr is the smallest number of saved_gpr. All gpr's \
|
||||
from saved_gpr to gpr31 are saved right under saved fprs, starting \
|
||||
from r31 first. */ \
|
||||
\
|
||||
if (saved_gpr >= 0) \
|
||||
for (ii=31; ii >= saved_gpr; --ii) \
|
||||
if (fdata.saved_gpr >= 0) \
|
||||
for (ii=31; ii >= fdata.saved_gpr; --ii) \
|
||||
(FRAME_SAVED_REGS).regs [ii] = frame_addr - ((32 - ii) * 4); \
|
||||
}
|
||||
|
||||
|
@ -555,9 +555,12 @@ register struct ld_info *ldi; {
|
||||
else {
|
||||
obj_err:
|
||||
bfd_close(bfd);
|
||||
#if 0
|
||||
/* FIXME -- bfd doesn't recognize /lib/libc.a as an archive */
|
||||
/* FIXME -- should be error */
|
||||
warning("\"%s\": not in executable format: %s."
|
||||
, ldi->ldinfo_filename, bfd_errmsg(bfd_error));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
129
gdb/xcoffread.c
129
gdb/xcoffread.c
@ -434,7 +434,7 @@ static void
|
||||
record_include_begin (cs)
|
||||
struct coff_symbol *cs;
|
||||
{
|
||||
/* In aixcoff, we assume include files cannot be nested (not in .c file
|
||||
/* In aixcoff, we assume include files cannot be nested (not in .c files
|
||||
of course, but in corresponding .s files.) */
|
||||
|
||||
if (inclDepth)
|
||||
@ -1266,9 +1266,10 @@ function_entry_point:
|
||||
parmvalue += sizeof (float);
|
||||
}
|
||||
}
|
||||
else { /* fixed parm */
|
||||
ADD_PARM_TO_PENDING
|
||||
(parm, parmvalue, builtin_type_int, local_symbols);
|
||||
else { /* fixed parm, use (int*) for hex rep. */
|
||||
ADD_PARM_TO_PENDING (parm, parmvalue,
|
||||
lookup_pointer_type (builtin_type_int),
|
||||
local_symbols);
|
||||
parmvalue += sizeof (int);
|
||||
}
|
||||
mask = mask >> 1;
|
||||
@ -1555,6 +1556,7 @@ process_xcoff_symbol (cs, objfile)
|
||||
struct type *ttype;
|
||||
char *name, *pp, *qq;
|
||||
int struct_and_type_combined;
|
||||
int nameless;
|
||||
|
||||
name = cs->c_name;
|
||||
if (name[0] == '.')
|
||||
@ -1602,10 +1604,11 @@ process_xcoff_symbol (cs, objfile)
|
||||
|
||||
case C_DECL: /* a type decleration?? */
|
||||
qq = (char*) strchr (name, ':');
|
||||
/* skip if there is no ':' or a nameless construct */
|
||||
if (!qq) /* skip if there is no ':' */
|
||||
return NULL;
|
||||
|
||||
nameless = (qq == name);
|
||||
|
||||
struct_and_type_combined = (qq[1] == 'T' && qq[2] == 't');
|
||||
pp = qq + (struct_and_type_combined ? 3 : 2);
|
||||
|
||||
@ -1622,7 +1625,7 @@ process_xcoff_symbol (cs, objfile)
|
||||
read_type_number (&tmp_pp, typenums);
|
||||
tmp_type = dbx_alloc_type (typenums);
|
||||
|
||||
if (tmp_type && !TYPE_NAME (tmp_type))
|
||||
if (tmp_type && !TYPE_NAME (tmp_type) && !nameless)
|
||||
TYPE_NAME (tmp_type) = SYMBOL_NAME (sym) =
|
||||
obsavestring (name, qq-name);
|
||||
}
|
||||
@ -1633,42 +1636,57 @@ process_xcoff_symbol (cs, objfile)
|
||||
there is no need to keep it in symbol table. */
|
||||
/* The above argument no longer valid. read_type() never returns NULL. */
|
||||
|
||||
if (!ttype || name == qq)
|
||||
if (!ttype)
|
||||
return NULL;
|
||||
|
||||
if (qq[1] == 'T')
|
||||
SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
|
||||
else if (qq[1] == 't')
|
||||
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
|
||||
else {
|
||||
printf ("ERROR: Unrecognized stab string.\n");
|
||||
return NULL;
|
||||
}
|
||||
/* if there is no name for this typedef, you don't have to keep its
|
||||
symbol, since nobody could ask for it. Otherwise, build a symbol
|
||||
and add it into symbol_list. */
|
||||
|
||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||
if (!SYMBOL_NAME (sym))
|
||||
SYMBOL_NAME (sym) =
|
||||
obsavestring (name, qq-name, &objfile->symbol_obstack);
|
||||
if (!nameless) {
|
||||
if (qq[1] == 'T')
|
||||
SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
|
||||
else if (qq[1] == 't')
|
||||
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
|
||||
else {
|
||||
printf ("ERROR: Unrecognized stab string.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (struct_and_type_combined)
|
||||
;
|
||||
else if (SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE)
|
||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||
if (!SYMBOL_NAME (sym))
|
||||
SYMBOL_NAME (sym) = obsavestring (name, qq-name,
|
||||
&objfile->symbol_obstack);
|
||||
|
||||
SYMBOL_DUP (sym, sym2);
|
||||
add_symbol_to_list
|
||||
(sym2, within_function ? &local_symbols : &file_symbols);
|
||||
|
||||
/* For a combination of struct and type, add one more symbol
|
||||
for the type. */
|
||||
|
||||
if (struct_and_type_combined) {
|
||||
SYMBOL_DUP (sym, sym2);
|
||||
SYMBOL_NAMESPACE (sym2) = VAR_NAMESPACE;
|
||||
add_symbol_to_list
|
||||
(sym2, within_function ? &local_symbols : &file_symbols);
|
||||
}
|
||||
}
|
||||
|
||||
/* assign a name to the type node. */
|
||||
|
||||
if (!nameless && (!TYPE_NAME (ttype) || *(TYPE_NAME (ttype)) == '\0')) {
|
||||
if (struct_and_type_combined)
|
||||
TYPE_NAME (ttype) = SYMBOL_NAME (sym);
|
||||
|
||||
/* else if (SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE) */
|
||||
else if (qq[1] == 'T') /* struct namespace */
|
||||
TYPE_NAME (ttype) = concat (
|
||||
TYPE_CODE (ttype) == TYPE_CODE_UNION ? "union " :
|
||||
TYPE_CODE (ttype) == TYPE_CODE_STRUCT? "struct " : "enum ",
|
||||
SYMBOL_NAME (sym), NULL);
|
||||
|
||||
SYMBOL_DUP (sym, sym2);
|
||||
add_symbol_to_list
|
||||
(sym2, within_function ? &local_symbols : &file_symbols);
|
||||
|
||||
/* For a combination of struct and type, add one more symbol for the type. */
|
||||
if (struct_and_type_combined) {
|
||||
SYMBOL_DUP (sym, sym2);
|
||||
SYMBOL_NAMESPACE (sym2) = VAR_NAMESPACE;
|
||||
add_symbol_to_list
|
||||
(sym2, within_function ? &local_symbols : &file_symbols);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case C_GSYM:
|
||||
@ -2194,6 +2212,51 @@ _initialize_xcoffread ()
|
||||
{
|
||||
add_symtab_fns(&aixcoff_sym_fns);
|
||||
}
|
||||
|
||||
|
||||
/* In order to handle forward type references, we needed to have this old
|
||||
routine. Try printing the type of member `p' in the following structure
|
||||
in a dbx environment.
|
||||
|
||||
struct s {
|
||||
...
|
||||
struct s *p;
|
||||
};
|
||||
*/
|
||||
#if 0
|
||||
/* Smash TYPE to be a type of pointers to TO_TYPE.
|
||||
If TO_TYPE is not permanent and has no pointer-type yet,
|
||||
record TYPE as its pointer-type. */
|
||||
|
||||
void
|
||||
smash_to_pointer_type (type, to_type)
|
||||
struct type *type, *to_type;
|
||||
{
|
||||
int type_permanent = (TYPE_FLAGS (type) & TYPE_FLAG_PERM);
|
||||
|
||||
bzero (type, sizeof (struct type));
|
||||
TYPE_TARGET_TYPE (type) = to_type;
|
||||
/* We assume the machine has only one representation for pointers! */
|
||||
TYPE_LENGTH (type) = sizeof (char *);
|
||||
TYPE_CODE (type) = TYPE_CODE_PTR;
|
||||
|
||||
/* ??? TYPE_TARGET_TYPE and TYPE_MAIN_VARIANT are the same. You can't do
|
||||
this. It will break the target type!!!
|
||||
TYPE_MAIN_VARIANT (type) = type;
|
||||
*/
|
||||
|
||||
if (type_permanent)
|
||||
TYPE_FLAGS (type) |= TYPE_FLAG_PERM;
|
||||
|
||||
if (TYPE_POINTER_TYPE (to_type) == 0
|
||||
&& (!(TYPE_FLAGS (to_type) & TYPE_FLAG_PERM)
|
||||
|| type_permanent))
|
||||
{
|
||||
TYPE_POINTER_TYPE (to_type) = type;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* IBM6000 */
|
||||
struct type *
|
||||
builtin_type (pp)
|
||||
|
@ -75,3 +75,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#ifndef IBM6000
|
||||
#define IBM6000
|
||||
#endif
|
||||
|
||||
/* /usr/include/stdlib.h always uses void* and void,
|
||||
even when __STDC__ isn't defined. */
|
||||
#define MALLOC_INCOMPATIBLE
|
||||
extern void* malloc PARAMS (());
|
||||
extern void* realloc PARAMS (());
|
||||
extern void free PARAMS (());
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user