Line 1052... |
Line 1052... |
}
|
}
|
|
|
if((len > bpw) && (argreg <= (OR32_LAST_ARG_REGNUM - 1)))
|
if((len > bpw) && (argreg <= (OR32_LAST_ARG_REGNUM - 1)))
|
{
|
{
|
|
|
/* Big scalars use two registers, must be pair aligned. This code
|
/* Big scalars use two registers, but need NOT be pair aligned. This
|
breaks if we can have quad-word scalars (e.g. long double). */
|
code breaks if we can have quad-word scalars (e.g. long
|
|
double). */
|
ULONGEST regval = extract_unsigned_integer (val, len, byte_order);
|
ULONGEST regval = extract_unsigned_integer (val, len, byte_order);
|
|
|
|
unsigned int bits_per_word = bpw * 8;
|
|
ULONGEST mask = (((ULONGEST) 1) << bits_per_word) - 1;
|
|
ULONGEST lo = regval & mask;
|
|
ULONGEST hi = regval >> bits_per_word;
|
|
|
gdb_assert (len <= (bpw * 2));
|
gdb_assert (len <= (bpw * 2));
|
|
|
argreg = 1 == (argreg & 1) ? argreg + 1 : argreg;
|
regcache_cooked_write_unsigned (regcache, argreg, hi);
|
regcache_cooked_write_unsigned (regcache, argreg, regval >> bpw);
|
regcache_cooked_write_unsigned (regcache, argreg + 1, lo);
|
regcache_cooked_write_unsigned (regcache, argreg + 1,
|
|
regval && ((ULONGEST)(1 << bpw) - 1));
|
|
argreg += 2;
|
argreg += 2;
|
}
|
}
|
else if (argreg <= OR32_LAST_ARG_REGNUM)
|
else if (argreg <= OR32_LAST_ARG_REGNUM)
|
{
|
{
|
|
printf ("Writing 0x%08llx to r%d\n",
|
|
extract_unsigned_integer (val, len, byte_order), argreg);
|
|
|
regcache_cooked_write_unsigned (regcache, argreg,
|
regcache_cooked_write_unsigned (regcache, argreg,
|
extract_unsigned_integer (val, len,
|
extract_unsigned_integer (val, len,
|
byte_order));
|
byte_order));
|
argreg++;
|
argreg++;
|
}
|
}
|
Line 1184... |
Line 1191... |
|
|
This function is changed from its GDB 6.8 version (named
|
This function is changed from its GDB 6.8 version (named
|
or32_frame_unwind_cache), in that it is based on THIS frame, not the NEXT
|
or32_frame_unwind_cache), in that it is based on THIS frame, not the NEXT
|
frame.
|
frame.
|
|
|
Build up the information (saved registers etc) for the given frame if it
|
We build a cache, saying where registers of the PREV frame can be found
|
does not already exist.
|
from the data so far set up in this THIS.
|
|
|
|
We also compute a unique ID for this frame, based on the function start
|
|
address and the stack pointer (as it will be, even if it has yet to be
|
|
computed.
|
|
|
STACK FORMAT
|
STACK FORMAT
|
============
|
============
|
|
|
The OR32 has a falling stack frame and a simple prolog. The Stack pointer
|
The OR32 has a falling stack frame and a simple prolog. The Stack pointer
|
Line 1237... |
Line 1248... |
========
|
========
|
|
|
This prolog is used, even for -O3 with GCC.
|
This prolog is used, even for -O3 with GCC.
|
|
|
All this analysis must allow for the possibility that the PC is in the
|
All this analysis must allow for the possibility that the PC is in the
|
middle of the prologue. Data should only be set up insofar as it has been
|
middle of the prologue. Data in the cache should only be set up insofar as
|
computed.
|
it has been computed.
|
|
|
|
HOWEVER. The frame_id must be created with the SP *as it will be* at the
|
|
end of the Prologue. Otherwise a recursive call, checking the frame with
|
|
the PC at the start address will end up with the same frame_id as the
|
|
caller.
|
|
|
A suite of "helper" routines are used, allowing reuse for
|
A suite of "helper" routines are used, allowing reuse for
|
or32_skip_prologue().
|
or32_skip_prologue().
|
|
|
Reportedly, this is only valid for frames less than 0x7fff in size.
|
Reportedly, this is only valid for frames less than 0x7fff in size.
|
Line 1260... |
Line 1276... |
struct gdbarch *gdbarch;
|
struct gdbarch *gdbarch;
|
struct trad_frame_cache *info;
|
struct trad_frame_cache *info;
|
|
|
CORE_ADDR this_pc;
|
CORE_ADDR this_pc;
|
CORE_ADDR this_sp;
|
CORE_ADDR this_sp;
|
|
CORE_ADDR this_sp_for_id;
|
int frame_size = 0;
|
int frame_size = 0;
|
|
|
CORE_ADDR start_addr;
|
CORE_ADDR start_addr;
|
CORE_ADDR end_addr;
|
CORE_ADDR end_addr;
|
|
|
Line 1292... |
Line 1309... |
we won't have a frame. */
|
we won't have a frame. */
|
this_sp = (NULL == this_frame) ? 0 :
|
this_sp = (NULL == this_frame) ? 0 :
|
get_frame_register_unsigned (this_frame,
|
get_frame_register_unsigned (this_frame,
|
OR32_SP_REGNUM);
|
OR32_SP_REGNUM);
|
|
|
/* The frame base of THIS frame (for ID purposes only - frame base is an
|
/* The default frame base of THIS frame (for ID purposes only - frame base
|
overloaded term) is its stack pointer. This is the same whether we are
|
is an overloaded term) is its stack pointer. For now we use the value of
|
frameless or not. */
|
the SP register in THIS frame. However if the PC is in the prologue of
|
|
THIS frame, before the SP has been set up, then the value will actually
|
|
be that of the PREV frame, and we'll need to adjust it later. */
|
trad_frame_set_this_base (info, this_sp);
|
trad_frame_set_this_base (info, this_sp);
|
|
this_sp_for_id = this_sp;
|
|
|
/* The default is to find the PC of the PREVIOUS frame in the link register
|
/* The default is to find the PC of the PREVIOUS frame in the link register
|
of this frame. This may be changed if we find the link register was saved
|
of this frame. This may be changed if we find the link register was saved
|
on the stack. */
|
on the stack. */
|
trad_frame_set_reg_realreg (info, OR32_NPC_REGNUM, OR32_LR_REGNUM);
|
trad_frame_set_reg_realreg (info, OR32_NPC_REGNUM, OR32_LR_REGNUM);
|
|
|
/* We should only examine code that is in the prologue and which has been
|
/* We should only examine code that is in the prologue. This is all code up
|
executed. This is all code up to (but not including) end_addr or the PC,
|
to (but not including) end_addr. We should only populate the cache while
|
whichever is first. */
|
the address is up to (but not including) the PC or end_addr, whichever is
|
|
first. */
|
gdbarch = get_frame_arch (this_frame);
|
gdbarch = get_frame_arch (this_frame);
|
end_addr = or32_skip_prologue (gdbarch, start_addr);
|
end_addr = or32_skip_prologue (gdbarch, start_addr);
|
end_addr = (this_pc > end_addr) ? end_addr : this_pc;
|
|
|
|
/* All the following analysis only occurs if we are in the prologue and have
|
/* All the following analysis only occurs if we are in the prologue and have
|
executed the code. Check we have a sane prologue size, and if zero we
|
executed the code. Check we have a sane prologue size, and if zero we
|
are frameless and can give up here. */
|
are frameless and can give up here. */
|
if (end_addr < start_addr)
|
if (end_addr < start_addr)
|
Line 1340... |
Line 1360... |
{
|
{
|
frame_size = -simm;
|
frame_size = -simm;
|
addr += OR32_INSTLEN;
|
addr += OR32_INSTLEN;
|
inst = or32_fetch_instruction (gdbarch, addr);
|
inst = or32_fetch_instruction (gdbarch, addr);
|
|
|
/* The stack pointer of the PREVIOUS frame is frame_size greater
|
/* If the PC has not actually got to this point, then the frame base
|
than the stack pointer of THIS frame. */
|
will be wrong, and we adjust it.
|
|
|
|
If we are past this point, then we need to populate the stack
|
|
accoringly. */
|
|
if (this_pc <= addr)
|
|
{
|
|
/* Only do if executing */
|
|
if (0 != this_sp)
|
|
{
|
|
this_sp_for_id = this_sp + frame_size;
|
|
trad_frame_set_this_base (info, this_sp_for_id);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* We are past this point, so the stack pointer of the PREV
|
|
frame is frame_size greater than the stack pointer of THIS
|
|
frame. */
|
trad_frame_set_reg_value (info, OR32_SP_REGNUM,
|
trad_frame_set_reg_value (info, OR32_SP_REGNUM,
|
this_sp + frame_size);
|
this_sp + frame_size);
|
}
|
}
|
|
}
|
|
|
|
/* From now on we are only populating the cache, so we stop once we get
|
|
to either the end OR the current PC. */
|
|
end_addr = (this_pc < end_addr) ? this_pc : end_addr;
|
|
|
/* Look for the frame pointer being manipulated. */
|
/* Look for the frame pointer being manipulated. */
|
if ((addr < end_addr) &&
|
if ((addr < end_addr) &&
|
or32_analyse_l_sw (inst, &simm, &ra, &rb) &&
|
or32_analyse_l_sw (inst, &simm, &ra, &rb) &&
|
(OR32_SP_REGNUM == ra) && (OR32_FP_REGNUM == rb) &&
|
(OR32_SP_REGNUM == ra) && (OR32_FP_REGNUM == rb) &&
|
Line 1418... |
Line 1460... |
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/* Build the frame ID */
|
/* Build the frame ID */
|
trad_frame_set_id (info, frame_id_build (this_sp, start_addr));
|
trad_frame_set_id (info, frame_id_build (this_sp_for_id, start_addr));
|
|
|
return info;
|
return info;
|
|
|
} /* or32_frame_cache() */
|
} /* or32_frame_cache() */
|
|
|