* mips-tdep.c (IS_MIPS16_ADDR, MAKE_MIPS16_ADDR, UNMAKE_MIPS16_ADDR):
New macros for testing, setting, and clearing bit 0 of addresses. Change numerous bits of code where bit 0 was being manipulated to use these macros.
This commit is contained in:
parent
35a3e78edb
commit
c1fc093571
|
@ -1,3 +1,10 @@
|
|||
Thu Feb 27 18:54:11 1997 Mark Alexander <marka@cygnus.com>
|
||||
|
||||
* mips-tdep.c (IS_MIPS16_ADDR, MAKE_MIPS16_ADDR, UNMAKE_MIPS16_ADDR):
|
||||
New macros for testing, setting, and clearing bit 0 of addresses.
|
||||
Change numerous bits of code where bit 0 was being manipulated
|
||||
to use these macros.
|
||||
|
||||
Thu Feb 27 14:12:41 1997 Mark Alexander <marka@cygnus.com>
|
||||
|
||||
* remote-mips.c: Put back the form feeds.
|
||||
|
|
107
gdb/mips-tdep.c
107
gdb/mips-tdep.c
|
@ -47,6 +47,12 @@ extern struct obstack frame_cache_obstack;
|
|||
#define MIPS_NUMREGS 32 /* Number of integer or float registers */
|
||||
typedef unsigned long t_inst; /* Integer big enough to hold an instruction */
|
||||
|
||||
/* MIPS16 function addresses are odd (bit 0 is set). Here are some
|
||||
macros to test, set, or clear bit 0 of addresses. */
|
||||
#define IS_MIPS16_ADDR(addr) ((addr) & 1)
|
||||
#define MAKE_MIPS16_ADDR(addr) ((addr) | 1)
|
||||
#define UNMAKE_MIPS16_ADDR(addr) ((addr) & ~1)
|
||||
|
||||
#if 0
|
||||
static int mips_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
|
||||
#endif
|
||||
|
@ -409,13 +415,15 @@ mips_find_saved_regs (fci)
|
|||
unsigned long gen_save_found = 0;
|
||||
unsigned long float_save_found = 0;
|
||||
|
||||
if ((addr = PROC_LOW_ADDR (proc_desc)) & 1)
|
||||
/* If the address is odd, assume this is MIPS16 code. */
|
||||
addr = PROC_LOW_ADDR (proc_desc);
|
||||
if (IS_MIPS16_ADDR (addr))
|
||||
{
|
||||
instlen = MIPS16_INSTLEN; /* MIPS16 */
|
||||
addr &= ~1;
|
||||
instlen = MIPS16_INSTLEN;
|
||||
addr = UNMAKE_MIPS16_ADDR (addr);
|
||||
}
|
||||
else
|
||||
instlen = MIPS_INSTLEN; /* MIPS32 */
|
||||
instlen = MIPS_INSTLEN;
|
||||
|
||||
/* Scan through this function's instructions preceding the current
|
||||
PC, and look for those that save registers. */
|
||||
|
@ -568,7 +576,7 @@ heuristic_proc_start(pc)
|
|||
|| fence < VM_MIN_ADDRESS)
|
||||
fence = VM_MIN_ADDRESS;
|
||||
|
||||
instlen = pc & 1 ? MIPS16_INSTLEN : MIPS_INSTLEN;
|
||||
instlen = IS_MIPS16_ADDR (pc) ? MIPS16_INSTLEN : MIPS_INSTLEN;
|
||||
|
||||
/* search back for previous return */
|
||||
for (start_pc -= instlen; ; start_pc -= instlen)
|
||||
|
@ -603,15 +611,17 @@ Otherwise, you told GDB there was a function where there isn't one, or\n\
|
|||
|
||||
return 0;
|
||||
}
|
||||
else if (start_pc & 1)
|
||||
else if (IS_MIPS16_ADDR (start_pc))
|
||||
{
|
||||
unsigned short inst;
|
||||
|
||||
/* On MIPS16, any one of the following is likely to be the
|
||||
start of a function:
|
||||
entry
|
||||
addiu sp,-n
|
||||
daddiu sp,-n
|
||||
extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n' */
|
||||
unsigned short inst = read_memory_integer (start_pc & ~1, 2);
|
||||
inst = read_memory_integer (UNMAKE_MIPS16_ADDR (start_pc), 2);
|
||||
if (((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */
|
||||
|| (inst & 0xff80) == 0x6380 /* addiu sp,-n */
|
||||
|| (inst & 0xff80) == 0xfb80 /* daddiu sp,-n */
|
||||
|
@ -699,7 +709,8 @@ mips16_heuristic_proc_desc(start_pc, limit_pc, next_frame, sp)
|
|||
prev_inst = inst;
|
||||
|
||||
/* Fetch the instruction. */
|
||||
status = read_memory_nobpt (cur_pc & ~1, buf, MIPS16_INSTLEN);
|
||||
status = read_memory_nobpt (UNMAKE_MIPS16_ADDR (cur_pc), buf,
|
||||
MIPS16_INSTLEN);
|
||||
if (status) memory_error (status, cur_pc);
|
||||
inst = (unsigned short) extract_unsigned_integer (buf, MIPS16_INSTLEN);
|
||||
|
||||
|
@ -922,7 +933,7 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
|
|||
|
||||
if (start_pc + 200 < limit_pc)
|
||||
limit_pc = start_pc + 200;
|
||||
if (start_pc & 1)
|
||||
if (IS_MIPS16_ADDR (start_pc))
|
||||
mips16_heuristic_proc_desc (start_pc, limit_pc, next_frame, sp);
|
||||
else
|
||||
mips32_heuristic_proc_desc (start_pc, limit_pc, next_frame, sp);
|
||||
|
@ -930,16 +941,18 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
|
|||
}
|
||||
|
||||
static mips_extra_func_info_t
|
||||
find_proc_desc (pc, next_frame)
|
||||
non_heuristic_proc_desc (pc, addrptr)
|
||||
CORE_ADDR pc;
|
||||
struct frame_info *next_frame;
|
||||
CORE_ADDR *addrptr;
|
||||
{
|
||||
CORE_ADDR startaddr;
|
||||
mips_extra_func_info_t proc_desc;
|
||||
struct block *b = block_for_pc(pc);
|
||||
struct symbol *sym;
|
||||
CORE_ADDR startaddr;
|
||||
|
||||
find_pc_partial_function (pc, NULL, &startaddr, NULL);
|
||||
if (addrptr)
|
||||
*addrptr = startaddr;
|
||||
if (b == NULL || PC_IN_CALL_DUMMY (pc, 0, 0))
|
||||
sym = NULL;
|
||||
else
|
||||
|
@ -950,16 +963,35 @@ find_proc_desc (pc, next_frame)
|
|||
symbol reading. */
|
||||
sym = NULL;
|
||||
else
|
||||
sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE,
|
||||
0, NULL);
|
||||
sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, 0, NULL);
|
||||
}
|
||||
|
||||
/* If we never found a PDR for this function in symbol reading, then
|
||||
examine prologues to find the information. */
|
||||
if (sym && ((mips_extra_func_info_t) SYMBOL_VALUE (sym))->pdr.framereg == -1)
|
||||
sym = NULL;
|
||||
|
||||
if (sym)
|
||||
{
|
||||
proc_desc = (mips_extra_func_info_t) SYMBOL_VALUE (sym);
|
||||
if (PROC_FRAME_REG (proc_desc) == -1)
|
||||
return NULL;
|
||||
else
|
||||
return proc_desc;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static mips_extra_func_info_t
|
||||
find_proc_desc (pc, next_frame)
|
||||
CORE_ADDR pc;
|
||||
struct frame_info *next_frame;
|
||||
{
|
||||
mips_extra_func_info_t proc_desc;
|
||||
CORE_ADDR startaddr;
|
||||
|
||||
proc_desc = non_heuristic_proc_desc (pc, &startaddr);
|
||||
|
||||
if (proc_desc)
|
||||
{
|
||||
/* IF this is the topmost frame AND
|
||||
* (this proc does not have debugging information OR
|
||||
|
@ -967,19 +999,21 @@ find_proc_desc (pc, next_frame)
|
|||
* THEN create a "heuristic" proc_desc (by analyzing
|
||||
* the actual code) to replace the "official" proc_desc.
|
||||
*/
|
||||
proc_desc = (mips_extra_func_info_t) SYMBOL_VALUE (sym);
|
||||
if (next_frame == NULL) {
|
||||
if (next_frame == NULL)
|
||||
{
|
||||
struct symtab_and_line val;
|
||||
struct symbol *proc_symbol =
|
||||
PROC_DESC_IS_DUMMY(proc_desc) ? 0 : PROC_SYMBOL(proc_desc);
|
||||
|
||||
if (proc_symbol) {
|
||||
if (proc_symbol)
|
||||
{
|
||||
val = find_pc_line (BLOCK_START
|
||||
(SYMBOL_BLOCK_VALUE(proc_symbol)),
|
||||
0);
|
||||
val.pc = val.end ? val.end : pc;
|
||||
}
|
||||
if (!proc_symbol || pc < val.pc) {
|
||||
if (!proc_symbol || pc < val.pc)
|
||||
{
|
||||
mips_extra_func_info_t found_heuristic =
|
||||
heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
|
||||
pc, next_frame);
|
||||
|
@ -1570,7 +1604,7 @@ mips_step_skips_delay (pc)
|
|||
char buf[MIPS_INSTLEN];
|
||||
|
||||
/* There is no branch delay slot on MIPS16. */
|
||||
if (pc & 1)
|
||||
if (IS_MIPS16_ADDR (pc))
|
||||
return 0;
|
||||
|
||||
if (target_read_memory (pc, buf, MIPS_INSTLEN) != 0)
|
||||
|
@ -1724,7 +1758,8 @@ mips16_skip_prologue (pc, lenient)
|
|||
int prev_extend_bytes;
|
||||
int i;
|
||||
|
||||
status = read_memory_nobpt (pc & ~1, buf, MIPS16_INSTLEN);
|
||||
status = read_memory_nobpt (UNMAKE_MIPS16_ADDR (pc), buf,
|
||||
MIPS16_INSTLEN);
|
||||
if (status)
|
||||
memory_error (status, pc);
|
||||
inst = (unsigned long)extract_unsigned_integer (buf, MIPS16_INSTLEN);
|
||||
|
@ -1788,7 +1823,7 @@ mips_skip_prologue (pc, lenient)
|
|||
/* Can't determine prologue from the symbol table, need to examine
|
||||
instructions. */
|
||||
|
||||
if (pc & 1)
|
||||
if (IS_MIPS16_ADDR (pc))
|
||||
return mips16_skip_prologue (pc, lenient);
|
||||
else
|
||||
return mips32_skip_prologue (pc, lenient);
|
||||
|
@ -2046,21 +2081,19 @@ gdb_print_insn_mips (memaddr, info)
|
|||
that is the start of a 16-bit function. If we didn't do this,
|
||||
the search would fail because the symbol table says the function
|
||||
starts at an odd address, i.e. 1 byte past the given address. */
|
||||
proc_desc = find_proc_desc (memaddr | 1, NULL);
|
||||
memaddr = ADDR_BITS_REMOVE (memaddr);
|
||||
proc_desc = non_heuristic_proc_desc (MAKE_MIPS16_ADDR (memaddr), NULL);
|
||||
|
||||
/* Make an attempt to determine if this is a 16-bit function. If
|
||||
the procedure descriptor exists and the address therein is odd,
|
||||
it's definitely a 16-bit function. Otherwise, we have to just
|
||||
guess that if the address passed in is odd, it's 16-bits. */
|
||||
if (proc_desc)
|
||||
info->mach = PROC_LOW_ADDR (proc_desc) & 1 ? 16 : 0;
|
||||
info->mach = IS_MIPS16_ADDR (PROC_LOW_ADDR (proc_desc)) ? 16 : 0;
|
||||
else
|
||||
info->mach = memaddr & 1 ? 16 : 0;
|
||||
info->mach = IS_MIPS16_ADDR (memaddr) ? 16 : 0;
|
||||
|
||||
/* Round down the instruction address to the appropriate boundary.
|
||||
Save the amount rounded down and subtract it from the returned size of
|
||||
the instruction so that the next time through the address won't
|
||||
look bogus. */
|
||||
/* Round down the instruction address to the appropriate boundary. */
|
||||
memaddr &= (info->mach == 16 ? ~1 : ~3);
|
||||
|
||||
/* Call the appropriate disassembler based on the target endian-ness. */
|
||||
|
@ -2083,10 +2116,10 @@ unsigned char *mips_breakpoint_from_pc (pcptr, lenptr)
|
|||
{
|
||||
if (TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
{
|
||||
if (*pcptr & 1)
|
||||
if (IS_MIPS16_ADDR (*pcptr))
|
||||
{
|
||||
static char mips16_big_breakpoint[] = MIPS16_BIG_BREAKPOINT;
|
||||
*pcptr &= ~1;
|
||||
*pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
|
||||
*lenptr = sizeof(mips16_big_breakpoint);
|
||||
return mips16_big_breakpoint;
|
||||
}
|
||||
|
@ -2099,10 +2132,10 @@ unsigned char *mips_breakpoint_from_pc (pcptr, lenptr)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (*pcptr & 1)
|
||||
if (IS_MIPS16_ADDR (*pcptr))
|
||||
{
|
||||
static char mips16_little_breakpoint[] = MIPS16_LITTLE_BREAKPOINT;
|
||||
*pcptr &= ~1;
|
||||
*pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
|
||||
*lenptr = sizeof(mips16_little_breakpoint);
|
||||
return mips16_little_breakpoint;
|
||||
}
|
||||
|
@ -2122,14 +2155,14 @@ int
|
|||
mips_about_to_return (pc)
|
||||
CORE_ADDR pc;
|
||||
{
|
||||
if (pc & 1)
|
||||
if (IS_MIPS16_ADDR (pc))
|
||||
/* This mips16 case isn't necessarily reliable. Sometimes the compiler
|
||||
generates a "jr $ra"; other times it generates code to load
|
||||
the return address from the stack to an accessible register (such
|
||||
as $a3), then a "jr" using that register. This second case
|
||||
is almost impossible to distinguish from an indirect jump
|
||||
used for switch statements, so we don't even try. */
|
||||
return read_memory_integer (pc & ~1, 2) == 0xe820; /* jr $ra */
|
||||
return read_memory_integer (UNMAKE_MIPS16_ADDR (pc), 2) == 0xe820; /* jr $ra */
|
||||
else
|
||||
return read_memory_integer (pc, 4) == 0x3e00008; /* jr $ra */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue