Added Irix 5 support.

* configure.in (mips-sgi-irix5*): New host and target.  Use irix5
	for both.
	* config/mips/irix5.mh, config/mips/irix5.mt,
	config/mips/xm-irix5.h, config/mips/nm-irix5.h,
	config/mips/tm-irix5.h, irix5-nat.c: New files for Irix 5 support.
	* mdebugread.c: New file, split out of mipsread.c.  Added
	elfmdebug_build_psymtabs routine.  Added some checks on external
	symbols.  Changed code to keep ecoff_debug_info and
	ecoff_debug_swap structs in the psymtab and in global pointers
	rather than retrieving them from the bfd.  Also changed to keep
	the pending list with the psymtab rather than the objfile (each
	psymtab for a single objfile points to the same pending list).
	* mipsread.c: Bulk of file moved into mdebugread.c, leaving just
	the sym_fns.
	* Makefile.in (SFILES): Added mdebugread.c.
	(OBS): Added mdebugread.o.
	(mdebugread.o): New target.
	* symfile.h: Declare mdebug_build_psymtabs and
	elfmdebug_build_psymtabs.
	* elfread.c (struct elfinfo): Added mdebugsect field.
	(elf_locate_sections): Remember location of .mdebug section.
	(elf_symfile_read): Call elfmdebug_build_psymtabs on .mdebug
	section.
	* infrun.c (AT_FUNCTION_START): Set to 0 if not already defined.
	(wait_for_inferior): Use AT_FUNCTION_START if it is defined to see
	if PC is at the start of a function.
	* mips-tdep.c (read_next_frame_reg): Use SIGFRAME_REG_SIZE, and
	give it a default definition.
	(mips_skip_prologue): Skip instructions which initialize $gp
	register.
	(in_sigtramp): New procedure, moved in from mipsread.c.
	* config/mips/tm-mips.h: Declare in_sigtramp.
This commit is contained in:
Ian Lance Taylor 1993-12-06 17:31:05 +00:00
parent a17535c780
commit e03c0cc670
6 changed files with 203 additions and 3637 deletions

View file

@ -1,3 +1,46 @@
Mon Dec 6 12:01:37 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
Added Irix 5 support.
* configure.in (mips-sgi-irix5*): New host and target. Use irix5
for both.
* config/mips/irix5.mh, config/mips/irix5.mt,
config/mips/xm-irix5.h, config/mips/nm-irix5.h,
config/mips/tm-irix5.h, irix5-nat.c: New files for Irix 5 support.
* mdebugread.c: New file, split out of mipsread.c. Added
elfmdebug_build_psymtabs routine. Added some checks on external
symbols. Changed code to keep ecoff_debug_info and
ecoff_debug_swap structs in the psymtab and in global pointers
rather than retrieving them from the bfd. Also changed to keep
the pending list with the psymtab rather than the objfile (each
psymtab for a single objfile points to the same pending list).
* mipsread.c: Bulk of file moved into mdebugread.c, leaving just
the sym_fns.
* Makefile.in (SFILES): Added mdebugread.c.
(OBS): Added mdebugread.o.
(mdebugread.o): New target.
* symfile.h: Declare mdebug_build_psymtabs and
elfmdebug_build_psymtabs.
* elfread.c (struct elfinfo): Added mdebugsect field.
(elf_locate_sections): Remember location of .mdebug section.
(elf_symfile_read): Call elfmdebug_build_psymtabs on .mdebug
section.
* infrun.c (AT_FUNCTION_START): Set to 0 if not already defined.
(wait_for_inferior): Use AT_FUNCTION_START if it is defined to see
if PC is at the start of a function.
* mips-tdep.c (read_next_frame_reg): Use SIGFRAME_REG_SIZE, and
give it a default definition.
(mips_skip_prologue): Skip instructions which initialize $gp
register.
(in_sigtramp): New procedure, moved in from mipsread.c.
* config/mips/tm-mips.h: Declare in_sigtramp.
* serial.h (serial_fdopen): Make parameter const to match
function definition.
Fri Dec 3 14:20:43 1993 Stu Grossman (grossman at cygnus.com)
* config/mips/irix4.mh: Enable ser-tcp.o.
Tue Nov 30 15:24:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* Makefile.in (check): Do not use subdir_do, so that

View file

@ -55,6 +55,7 @@ extern CORE_ADDR mips_skip_prologue PARAMS ((CORE_ADDR addr, int lenient));
/* Are we currently handling a signal */
extern int in_sigtramp PARAMS ((CORE_ADDR, char *));
#define IN_SIGTRAMP(pc, name) in_sigtramp(pc, name)
/* Stack grows downward. */

View file

@ -88,6 +88,7 @@ mips-dec-*) gdb_host=decstation ;;
mips-little-*) gdb_host=littlemips ;;
mips-sgi-irix3*) gdb_host=irix3 ;;
mips-sgi-irix4*) gdb_host=irix4 ;;
mips-sgi-irix5*) gdb_host=irix5 ;;
mips-sony-*) gdb_host=news-mips ;;
mips-*-sysv*) gdb_host=riscos ;;
mips-*-riscos*) gdb_host=riscos ;;
@ -257,6 +258,7 @@ mips-dec-*) gdb_target=decstation ;;
mips-idt-ecoffl*) gdb_target=idtl ;;
mips-idt-ecoff*) gdb_target=idt ;;
mips-little-*) gdb_target=littlemips ;;
mips-sgi-irix5*) gdb_target=irix5 ;;
mips-sgi-*) gdb_target=irix3 ;;
mips-sony-*) gdb_target=bigmips ;;
mips-*-sysv*) gdb_target=bigmips ;;

View file

@ -45,6 +45,7 @@ struct elfinfo {
unsigned int lnsize; /* Size of dwarf line number section */
asection *stabsect; /* Section pointer for .stab section */
asection *stabindexsect; /* Section pointer for .stab.index section */
asection *mdebugsect; /* Section pointer for .mdebug section */
};
/* Various things we might complain about... */
@ -136,6 +137,10 @@ elf_locate_sections (ignore_abfd, sectp, eip)
{
ei -> stabindexsect = sectp;
}
else if (STREQ (sectp -> name, ".mdebug"))
{
ei -> mdebugsect = sectp;
}
}
#if 0 /* Currently unused */
@ -447,7 +452,8 @@ elf_symtab_read (abfd, addr, objfile)
format to look for: FIXME!!!
dwarf_build_psymtabs() builds psymtabs for DWARF symbols;
elfstab_build_psymtabs() handles STABS symbols.
elfstab_build_psymtabs() handles STABS symbols;
mdebug_build_psymtabs() handles ECOFF debugging information.
Note that ELF files have a "minimal" symbol table, which looks a lot
like a COFF symbol table, but has only the minimal information necessary
@ -519,6 +525,17 @@ elf_symfile_read (objfile, section_offsets, mainline)
(file_ptr) elf_sect->sh_offset, /* .stabstr offset */
elf_sect->sh_size); /* .stabstr size */
}
if (ei.mdebugsect)
{
const struct ecoff_debug_swap *swap;
/* .mdebug section, presumably holding ECOFF debugging
information. */
swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
if (swap)
elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect,
section_offsets);
}
if (!have_partial_symbols ())
{

View file

@ -78,17 +78,19 @@ read_next_frame_reg(fi, regno)
/* If it is the frame for sigtramp we have a complete sigcontext
immediately below the frame and we get the saved registers from there.
If the stack layout for sigtramp changes we might have to change these
constants and the companion fixup_sigtramp in mipsread.c */
constants and the companion fixup_sigtramp in mdebugread.c */
#ifndef SIGFRAME_BASE
#define SIGFRAME_BASE 0x12c /* sizeof(sigcontext) */
#define SIGFRAME_PC_OFF (-SIGFRAME_BASE + 2 * 4)
#define SIGFRAME_REGSAVE_OFF (-SIGFRAME_BASE + 3 * 4)
#define SIGFRAME_REG_SIZE 4
#endif
for (; fi; fi = fi->next)
if (in_sigtramp(fi->pc, 0)) {
int offset;
if (regno == PC_REGNUM) offset = SIGFRAME_PC_OFF;
else if (regno < 32) offset = SIGFRAME_REGSAVE_OFF + regno * 4;
else if (regno < 32) offset = (SIGFRAME_REGSAVE_OFF
+ regno * SIGFRAME_REG_SIZE);
else return 0;
return read_memory_integer(fi->frame + offset, 4);
}
@ -185,7 +187,7 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
CORE_ADDR cur_pc;
int frame_size;
int has_frame_reg = 0;
int reg30; /* Value of $r30. Used by gcc for frame-pointer */
int reg30 = 0; /* Value of $r30. Used by gcc for frame-pointer */
unsigned long reg_mask = 0;
if (start_pc == 0) return NULL;
@ -224,7 +226,7 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
alloca_adjust = reg30 - (sp + (word & 0xffff));
if (alloca_adjust > 0) {
/* FP > SP + frame_size. This may be because
/* of an alloca or somethings similar.
* of an alloca or somethings similar.
* Fix sp to "pre-alloca" value, and try again.
*/
sp += alloca_adjust;
@ -376,7 +378,6 @@ init_extra_frame_info(fci)
{
int ireg;
CORE_ADDR reg_position;
unsigned long mask;
/* r0 bit means kernel trap */
int kernel_trap = PROC_REG_MASK(proc_desc) & 1;
@ -390,99 +391,101 @@ init_extra_frame_info(fci)
if (proc_desc == &temp_proc_desc)
*fci->saved_regs = temp_saved_regs;
else if (/* In any frame other than the innermost, we assume that all
registers have been saved. This assumes that all register
saves in a function happen before the first function
call. */
fci->next != NULL
/* In a dummy frame we know exactly where things are saved. */
|| PROC_DESC_IS_DUMMY (proc_desc)
/* Not sure exactly what kernel_trap means, but if it means
the kernel saves the registers without a prologue doing it,
we better not examine the prologue to see whether registers
have been saved yet. */
|| kernel_trap)
else
{
/* All the registers which will be saved have been saved, so we
can believe the proc_desc. */
/* What registers have been saved? Bitmasks. */
unsigned long gen_mask, float_mask;
/* find which general-purpose registers were saved */
reg_position = fci->frame + PROC_REG_OFFSET(proc_desc);
mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc);
for (ireg= 31; mask; --ireg, mask <<= 1)
if (mask & 0x80000000)
gen_mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc);
float_mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK(proc_desc);
if (/* In any frame other than the innermost, we assume that all
registers have been saved. This assumes that all register
saves in a function happen before the first function
call. */
fci->next == NULL
/* In a dummy frame we know exactly where things are saved. */
&& !PROC_DESC_IS_DUMMY (proc_desc)
/* Not sure exactly what kernel_trap means, but if it means
the kernel saves the registers without a prologue doing it,
we better not examine the prologue to see whether registers
have been saved yet. */
&& !kernel_trap)
{
/* We need to figure out whether the registers that the proc_desc
claims are saved have been saved yet. */
CORE_ADDR addr;
int status;
char buf[4];
unsigned long inst;
/* Bitmasks; set if we have found a save for the register. */
unsigned long gen_save_found = 0;
unsigned long float_save_found = 0;
for (addr = PROC_LOW_ADDR (proc_desc);
addr < fci->pc && (gen_mask != gen_save_found
|| float_mask != float_save_found);
addr += 4)
{
status = read_memory_nobpt (addr, buf, 4);
if (status)
memory_error (status, addr);
inst = extract_unsigned_integer (buf, 4);
if (/* sw reg,n($sp) */
(inst & 0xffe00000) == 0xafa00000
/* sw reg,n($r30) */
|| (inst & 0xffe00000) == 0xafc00000)
{
/* It might be possible to use the instruction to
find the offset, rather than the code below which
is based on things being in a certain order in the
frame, but figuring out what the instruction's offset
is relative to might be a little tricky. */
int reg = (inst & 0x001f0000) >> 16;
gen_save_found |= (1 << reg);
}
else if (/* swc1 freg,n($sp) */
(inst & 0xffe00000) == 0xe7a00000
/* swc1 freg,n($r30) */
|| (inst & 0xffe00000) == 0xe7c00000)
{
int reg = ((inst & 0x001f0000) >> 16);
float_save_found |= (1 << reg);
}
}
gen_mask = gen_save_found;
float_mask = float_save_found;
}
/* Fill in the offsets for the registers which gen_mask says
were saved. */
reg_position = fci->frame + PROC_REG_OFFSET (proc_desc);
for (ireg= 31; gen_mask; --ireg, gen_mask <<= 1)
if (gen_mask & 0x80000000)
{
fci->saved_regs->regs[ireg] = reg_position;
reg_position -= 4;
}
/* find which floating-point registers were saved */
reg_position = fci->frame + PROC_FREG_OFFSET(proc_desc);
/* Fill in the offsets for the registers which float_mask says
were saved. */
reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc);
/* The freg_offset points to where the first *double* register
is saved. So skip to the high-order word. */
reg_position += 4;
mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK(proc_desc);
for (ireg = 31; mask; --ireg, mask <<= 1)
if (mask & 0x80000000)
for (ireg = 31; float_mask; --ireg, float_mask <<= 1)
if (float_mask & 0x80000000)
{
fci->saved_regs->regs[FP0_REGNUM+ireg] = reg_position;
reg_position -= 4;
}
}
else
{
/* We need to figure out whether the registers that the proc_desc
claims are saved have been saved yet. */
CORE_ADDR addr;
int status;
char buf[4];
unsigned long inst;
/* Bitmasks; set if the proc_desc claims the register is saved and we
haven't found a save instruction for it yet. */
unsigned long gen_mask, float_mask;
gen_mask = PROC_REG_MASK (proc_desc);
float_mask = PROC_FREG_MASK (proc_desc);
for (addr = PROC_LOW_ADDR (proc_desc);
addr < fci->pc && (gen_mask | float_mask);
addr += 4)
{
status = read_memory_nobpt (addr, buf, 4);
if (status)
memory_error (status, addr);
inst = extract_unsigned_integer (buf, 4);
if (/* sw reg,n($sp) */
(inst & 0xffe00000) == 0xafa00000
/* sw reg,n($r30) */
|| (inst & 0xffe00000) == 0xafc00000)
{
/* We assume that all saves are relative to the
PROC_FRAME_REG, which is what we used to set up
->frame. */
int reg = (inst & 0x001f0000) >> 16;
if (gen_mask & (1 << reg))
fci->saved_regs.regs[reg] = fci->frame + (inst & 0xffff);
gen_mask &= ~(1 << reg);
}
else if (/* swc1 freg,n($sp) */
(inst & 0xffe00000) == 0xe7a00000
/* swc1 freg,n($r30) */
(inst & 0xffe00000) == 0xe7c00000)
{
int reg = ((inst & 0x001f0000) >> 16);
if (float_mask & (1 << reg))
fci->saved_regs.regs[FP0_REGNUM + reg]
= fci->frame + (inst & 0xffff);
float_mask &= ~(1 << reg);
}
}
}
/* hack: if argument regs are saved, guess these contain args */
if ((PROC_REG_MASK(proc_desc) & 0xF0) == 0) fci->num_args = -1;
@ -566,7 +569,7 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
}
/* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<31. */
#define MASK(i,j) ((1 << (j)+1)-1 ^ (1 << (i))-1)
#define MASK(i,j) (((1 << ((j)+1))-1) ^ ((1 << (i))-1))
void
mips_push_dummy_frame()
@ -713,7 +716,6 @@ mips_print_register (regnum, all)
int regnum, all;
{
unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE];
REGISTER_TYPE val;
/* Get the data in raw format. */
if (read_relative_register_raw_bytes (regnum, raw_buffer))
@ -847,8 +849,6 @@ mips_skip_prologue (pc, lenient)
CORE_ADDR pc;
int lenient;
{
struct symbol *f;
struct block *b;
unsigned long inst;
int offset;
int seen_sp_adjust = 0;
@ -885,6 +885,13 @@ mips_skip_prologue (pc, lenient)
continue;
else if ((inst & 0xFF9F07FF) == 0x00800021) /* move reg,$a0-$a3 */
continue;
else if ((inst & 0xffff0000) == 0x3c1c0000) /* lui $gp,n */
continue;
else if ((inst & 0xffff0000) == 0x279c0000) /* addiu $gp,$gp,n */
continue;
else if (inst == 0x0399e021 /* addu $gp,$gp,$t9 */
|| inst == 0x033ce021) /* addu $gp,$t9,$gp */
continue;
else
break;
}
@ -976,6 +983,22 @@ mips_store_return_value (valtype, valbuf)
write_register_bytes(REGISTER_BYTE (regnum), raw_buffer, TYPE_LENGTH (valtype));
}
/* These exist in mdebugread.c. */
extern CORE_ADDR sigtramp_address, sigtramp_end;
extern void fixup_sigtramp PARAMS ((void));
/* Exported procedure: Is PC in the signal trampoline code */
int
in_sigtramp (pc, ignore)
CORE_ADDR pc;
char *ignore; /* function name */
{
if (sigtramp_address == 0)
fixup_sigtramp ();
return (pc >= sigtramp_address && pc < sigtramp_end);
}
static void reinit_frame_cache_sfunc PARAMS ((char *, int,
struct cmd_list_element *));

File diff suppressed because it is too large Load diff