* [RFA] Add support for 64-bit MIPS GNU/Linux targets
@ 2002-12-23 15:07 Kevin Buettner
2002-12-23 16:01 ` Daniel Jacobowitz
0 siblings, 1 reply; 10+ messages in thread
From: Kevin Buettner @ 2002-12-23 15:07 UTC (permalink / raw)
To: gdb-patches
The patch below adds GNU/Linux specific support for the n32 and n64
MIPS ABIs.
I've been able to do both core file debugging and remote debugging
using this patch when GDB is built as a cross debugger to a
mips64-linux target. Unfortunately, I am not presently able to
(completely) build a native mips64-linux debugger due to issues in
other parts of the toolchain.
Okay to commit?
* Makefile.in (mips-linux-tdep.o): Add $(mips_tdep_h) and
$(gdb_assert_h).
* configure.tgt: Recognize mips64*-*-linux*.
* mips-linux-tdep.c (mips-tdep.h, gdb_assert.h): Include.
(supply_32_bit_reg): New function.
(supply_gregset): Call supply_32bit_reg() instead of supply_register().
(fill_gregset): Use regcache_collect() instead of
deprecated_registers[].
(register_addr): Change name to mips_linux_register_addr().
(MIPS64_ELF_NGREG, MIPS64_ELF_NFPREG, MIPS64_FPR_BASE, MIPS64_PC)
(MIPS64_CAUSE, MIPS64_BADVADDR, MIPS64_MMHI, MIPS64_MMLO)
(MIPS64_FPC_CSR, MIPS64_FPC_EIR, MIPS64_EF_REG0, MIPS64_EF_REG31)
(MIPS64_EF_LO, MIPS64_EF_HI, MIPS64_EF_CP0_EPC, MIPS64_EF_CP0_BADVADDR)
(MIPS64_EF_CP0_STATUS, MIPS64_EF_CP0_CAUSE, MIPS64_EF_SIZE)
(MIPS64_LINUX_JB_PC): New defines.
(mips64_elf_greg_t, mips64_elf_gregset_t, mips64_elf_fpreg_t)
(mips64_elf_fpregset_t): New typedefs.
(mips64_linux_get_longhmp_target, mips64_supply_gregset)
(mips64_fill_gregset, mips64_supply_fpregset, mips64_fill_fpregset)
(mips64_linux_register_addr, set_mips_linux_register_addr)
(register_addr, mips64_linux_svr4_fetch_link_map_offsets):
(init_register_addr_data)
New functions.
(fetch_core_registers): Add support for core file formats with 64-bit
registers.
(mips_linux_init_abi): Distinguish o32, n32, and n64 ABIs.
(register_addr_data): New static global variable.
(_initialize_mips_linux_tdep): Initialize register_addr_data.
* config/mips/linux64.mt: New file.
* config/mips/tm-linux64.h: New file.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.297
diff -u -p -r1.297 Makefile.in
--- Makefile.in 21 Dec 2002 05:07:36 -0000 1.297
+++ Makefile.in 23 Dec 2002 22:35:28 -0000
@@ -1946,7 +1946,8 @@ minsyms.o: minsyms.c $(defs_h) $(gdb_str
mips-irix-tdep.o: mips-irix-tdep.c $(defs_h) $(osabi_h) $(elf_bfd_h)
mips-linux-nat.o: mips-linux-nat.c $(defs_h)
mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
- $(solib_svr4_h) $(osabi_h) $(gdb_string_h)
+ $(solib_svr4_h) $(osabi_h) $(gdb_string_h) $(mips_tdep_h) \
+ $(gdb_assert_h)
mips-nat.o: mips-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h)
mips-tdep.o: mips-tdep.c $(defs_h) $(gdb_string_h) $(frame_h) $(inferior_h) \
$(symtab_h) $(value_h) $(gdbcmd_h) $(language_h) $(gdbcore_h) \
Index: configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.87
diff -u -p -r1.87 configure.tgt
--- configure.tgt 20 Oct 2002 11:54:40 -0000 1.87
+++ configure.tgt 23 Dec 2002 22:35:28 -0000
@@ -189,6 +189,7 @@ mips*tx39*el*-elf*) gdb_target=tx39l ;;
mips*tx39*-elf*) gdb_target=tx39 ;;
mips64*el-*-elf*) gdb_target=embedl64 ;;
mips64*-*-elf*) gdb_target=embed64 ;;
+mips64*-*-linux*) gdb_target=linux64 ;;
mips*el-*-ecoff*) gdb_target=embedl ;;
mips*-*-ecoff*) gdb_target=embed ;;
mips*el-*-elf*) gdb_target=embedl ;;
Index: mips-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-linux-tdep.c,v
retrieving revision 1.8
diff -u -p -r1.8 mips-linux-tdep.c
--- mips-linux-tdep.c 21 Dec 2002 19:58:07 -0000 1.8
+++ mips-linux-tdep.c 23 Dec 2002 22:35:28 -0000
@@ -24,7 +24,9 @@
#include "target.h"
#include "solib-svr4.h"
#include "osabi.h"
+#include "mips-tdep.h"
#include "gdb_string.h"
+#include "gdb_assert.h"
/* Copied from <asm/elf.h>. */
#define ELF_NGREG 45
@@ -83,6 +85,18 @@ mips_linux_get_longjmp_target (CORE_ADDR
return 1;
}
+/* Transform the bits comprising a 32-bit register to the right
+ size for supply_register(). This is needed when MIPS_REGSIZE is 8. */
+
+static void
+supply_32bit_reg (int regnum, const void *addr)
+{
+ char *buf = alloca (MAX_REGISTER_RAW_SIZE);
+ store_signed_integer (buf, REGISTER_RAW_SIZE (regnum),
+ extract_signed_integer (addr, 4));
+ supply_register (regnum, buf);
+}
+
/* Unpack an elf_gregset_t into GDB's register cache. */
void
@@ -95,15 +109,15 @@ supply_gregset (elf_gregset_t *gregsetp)
memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
for (regi = EF_REG0; regi <= EF_REG31; regi++)
- supply_register ((regi - EF_REG0), (char *)(regp + regi));
+ supply_32bit_reg ((regi - EF_REG0), (char *)(regp + regi));
- supply_register (LO_REGNUM, (char *)(regp + EF_LO));
- supply_register (HI_REGNUM, (char *)(regp + EF_HI));
+ supply_32bit_reg (LO_REGNUM, (char *)(regp + EF_LO));
+ supply_32bit_reg (HI_REGNUM, (char *)(regp + EF_HI));
- supply_register (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
- supply_register (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
- supply_register (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
- supply_register (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
+ supply_32bit_reg (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
+ supply_32bit_reg (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
+ supply_32bit_reg (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
+ supply_32bit_reg (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
/* Fill inaccessible registers with zero. */
supply_register (UNUSED_REGNUM, zerobuf);
@@ -118,7 +132,7 @@ fill_gregset (elf_gregset_t *gregsetp, i
{
int regaddr, regi;
elf_greg_t *regp = *gregsetp;
- void *src, *dst;
+ void *dst;
if (regno == -1)
{
@@ -137,9 +151,8 @@ fill_gregset (elf_gregset_t *gregsetp, i
if (regno < 32)
{
- src = &deprecated_registers[REGISTER_BYTE (regno)];
dst = regp + regno + EF_REG0;
- memcpy (dst, src, sizeof (elf_greg_t));
+ regcache_collect (regno, dst);
return;
}
@@ -168,9 +181,8 @@ fill_gregset (elf_gregset_t *gregsetp, i
if (regaddr != -1)
{
- src = &deprecated_registers[REGISTER_BYTE (regno)];
dst = regp + regaddr;
- memcpy (dst, src, sizeof (elf_greg_t));
+ regcache_collect (regno, dst);
}
}
@@ -227,8 +239,8 @@ fill_fpregset (elf_fpregset_t *fpregsetp
/* Map gdb internal register number to ptrace ``address''.
These ``addresses'' are normally defined in <asm/ptrace.h>. */
-CORE_ADDR
-register_addr (int regno, CORE_ADDR blockend)
+static CORE_ADDR
+mips_linux_register_addr (int regno, CORE_ADDR blockend)
{
int regaddr;
@@ -259,6 +271,282 @@ register_addr (int regno, CORE_ADDR bloc
return regaddr;
}
+
+/* Fetch (and possibly build) an appropriate link_map_offsets
+ structure for native GNU/Linux MIPS targets using the struct offsets
+ defined in link.h (but without actual reference to that file).
+
+ This makes it possible to access GNU/Linux MIPS shared libraries from a
+ GDB that was built on a different host platform (for cross debugging). */
+
+static struct link_map_offsets *
+mips_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
+ this is all we need. */
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20;
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+/* Support for 64-bit ABIs. */
+
+/* Copied from <asm/elf.h>. */
+#define MIPS64_ELF_NGREG 45
+#define MIPS64_ELF_NFPREG 33
+
+typedef unsigned char mips64_elf_greg_t[8];
+typedef mips64_elf_greg_t mips64_elf_gregset_t[MIPS64_ELF_NGREG];
+
+typedef unsigned char mips64_elf_fpreg_t[8];
+typedef mips64_elf_fpreg_t mips64_elf_fpregset_t[MIPS64_ELF_NFPREG];
+
+/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
+#define MIPS64_FPR_BASE 32
+#define MIPS64_PC 64
+#define MIPS64_CAUSE 65
+#define MIPS64_BADVADDR 66
+#define MIPS64_MMHI 67
+#define MIPS64_MMLO 68
+#define MIPS64_FPC_CSR 69
+#define MIPS64_FPC_EIR 70
+
+#define MIPS64_EF_REG0 0
+#define MIPS64_EF_REG31 31
+#define MIPS64_EF_LO 32
+#define MIPS64_EF_HI 33
+#define MIPS64_EF_CP0_EPC 34
+#define MIPS64_EF_CP0_BADVADDR 35
+#define MIPS64_EF_CP0_STATUS 36
+#define MIPS64_EF_CP0_CAUSE 37
+
+#define MIPS64_EF_SIZE 304
+
+/* 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 (MIPS_LINUX_JB_PC) that we will land at. The pc
+ is copied into PC. This routine returns 1 on success. */
+
+/* Details about jmp_buf. */
+
+#define MIPS64_LINUX_JB_PC 0
+
+static int
+mips64_linux_get_longjmp_target (CORE_ADDR *pc)
+{
+ CORE_ADDR jb_addr;
+ void *buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ int element_size = TARGET_PTR_BIT == 32 ? 4 : 8;
+
+ jb_addr = read_register (A0_REGNUM);
+
+ if (target_read_memory (jb_addr + MIPS64_LINUX_JB_PC * element_size,
+ buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ return 1;
+}
+
+/* Unpack an elf_gregset_t into GDB's register cache. */
+
+static void
+mips64_supply_gregset (mips64_elf_gregset_t *gregsetp)
+{
+ int regi;
+ mips64_elf_greg_t *regp = *gregsetp;
+ char *zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
+
+ memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
+
+ for (regi = MIPS64_EF_REG0; regi <= MIPS64_EF_REG31; regi++)
+ supply_register ((regi - MIPS64_EF_REG0), (char *)(regp + regi));
+
+ supply_register (LO_REGNUM, (char *)(regp + MIPS64_EF_LO));
+ supply_register (HI_REGNUM, (char *)(regp + MIPS64_EF_HI));
+
+ supply_register (PC_REGNUM, (char *)(regp + MIPS64_EF_CP0_EPC));
+ supply_register (BADVADDR_REGNUM, (char *)(regp + MIPS64_EF_CP0_BADVADDR));
+ supply_register (PS_REGNUM, (char *)(regp + MIPS64_EF_CP0_STATUS));
+ supply_register (CAUSE_REGNUM, (char *)(regp + MIPS64_EF_CP0_CAUSE));
+
+ /* Fill inaccessible registers with zero. */
+ supply_register (UNUSED_REGNUM, zerobuf);
+ for (regi = FIRST_EMBED_REGNUM; regi < LAST_EMBED_REGNUM; regi++)
+ supply_register (regi, zerobuf);
+}
+
+/* Pack our registers (or one register) into an elf_gregset_t. */
+
+static void
+mips64_fill_gregset (mips64_elf_gregset_t *gregsetp, int regno)
+{
+ int regaddr, regi;
+ mips64_elf_greg_t *regp = *gregsetp;
+ void *src, *dst;
+
+ if (regno == -1)
+ {
+ memset (regp, 0, sizeof (mips64_elf_gregset_t));
+ for (regi = 0; regi < 32; regi++)
+ mips64_fill_gregset (gregsetp, regi);
+ mips64_fill_gregset (gregsetp, LO_REGNUM);
+ mips64_fill_gregset (gregsetp, HI_REGNUM);
+ mips64_fill_gregset (gregsetp, PC_REGNUM);
+ mips64_fill_gregset (gregsetp, BADVADDR_REGNUM);
+ mips64_fill_gregset (gregsetp, PS_REGNUM);
+ mips64_fill_gregset (gregsetp, CAUSE_REGNUM);
+
+ return;
+ }
+
+ if (regno < 32)
+ {
+ dst = regp + regno + MIPS64_EF_REG0;
+ regcache_collect (regno, dst);
+ return;
+ }
+
+ regaddr = -1;
+ switch (regno)
+ {
+ case LO_REGNUM:
+ regaddr = MIPS64_EF_LO;
+ break;
+ case HI_REGNUM:
+ regaddr = MIPS64_EF_HI;
+ break;
+ case PC_REGNUM:
+ regaddr = MIPS64_EF_CP0_EPC;
+ break;
+ case BADVADDR_REGNUM:
+ regaddr = MIPS64_EF_CP0_BADVADDR;
+ break;
+ case PS_REGNUM:
+ regaddr = MIPS64_EF_CP0_STATUS;
+ break;
+ case CAUSE_REGNUM:
+ regaddr = MIPS64_EF_CP0_CAUSE;
+ break;
+ }
+
+ if (regaddr != -1)
+ {
+ dst = regp + regaddr;
+ regcache_collect (regno, dst);
+ }
+}
+
+/* Likewise, unpack an elf_fpregset_t. */
+
+static void
+mips64_supply_fpregset (mips64_elf_fpregset_t *fpregsetp)
+{
+ register int regi;
+ char *zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
+
+ memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
+
+ for (regi = 0; regi < 32; regi++)
+ supply_register (FP0_REGNUM + regi,
+ (char *)(*fpregsetp + regi));
+
+ supply_register (FCRCS_REGNUM, (char *)(*fpregsetp + 32));
+
+ /* FIXME: how can we supply FCRIR_REGNUM? The ABI doesn't tell us. */
+ supply_register (FCRIR_REGNUM, zerobuf);
+}
+
+/* Likewise, pack one or all floating point registers into an
+ elf_fpregset_t. */
+
+static void
+mips64_fill_fpregset (mips64_elf_fpregset_t *fpregsetp, int regno)
+{
+ char *from, *to;
+
+ if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
+ {
+ from = (char *) &deprecated_registers[REGISTER_BYTE (regno)];
+ to = (char *) (*fpregsetp + regno - FP0_REGNUM);
+ memcpy (to, from, REGISTER_RAW_SIZE (regno - FP0_REGNUM));
+ }
+ else if (regno == FCRCS_REGNUM)
+ {
+ from = (char *) &deprecated_registers[REGISTER_BYTE (regno)];
+ to = (char *) (*fpregsetp + 32);
+ memcpy (to, from, REGISTER_RAW_SIZE (regno));
+ }
+ else if (regno == -1)
+ {
+ int regi;
+
+ for (regi = 0; regi < 32; regi++)
+ mips64_fill_fpregset (fpregsetp, FP0_REGNUM + regi);
+ mips64_fill_fpregset(fpregsetp, FCRCS_REGNUM);
+ }
+}
+
+
+/* Map gdb internal register number to ptrace ``address''.
+ These ``addresses'' are normally defined in <asm/ptrace.h>. */
+
+static CORE_ADDR
+mips64_linux_register_addr (int regno, CORE_ADDR blockend)
+{
+ int regaddr;
+
+ if (regno < 0 || regno >= NUM_REGS)
+ error ("Bogon register number %d.", regno);
+
+ if (regno < 32)
+ regaddr = regno;
+ else if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
+ regaddr = MIPS64_FPR_BASE + (regno - FP0_REGNUM);
+ else if (regno == PC_REGNUM)
+ regaddr = MIPS64_PC;
+ else if (regno == CAUSE_REGNUM)
+ regaddr = MIPS64_CAUSE;
+ else if (regno == BADVADDR_REGNUM)
+ regaddr = MIPS64_BADVADDR;
+ else if (regno == LO_REGNUM)
+ regaddr = MIPS64_MMLO;
+ else if (regno == HI_REGNUM)
+ regaddr = MIPS64_MMHI;
+ else if (regno == FCRCS_REGNUM)
+ regaddr = MIPS64_FPC_CSR;
+ else if (regno == FCRIR_REGNUM)
+ regaddr = MIPS64_FPC_EIR;
+ else
+ error ("Unknowable register number %d.", regno);
+
+ return regaddr;
+}
+
/* Use a local version of this function to get the correct types for
regsets, until multi-arch core support is ready. */
@@ -268,29 +556,41 @@ fetch_core_registers (char *core_reg_sec
{
elf_gregset_t gregset;
elf_fpregset_t fpregset;
+ mips64_elf_gregset_t gregset64;
+ mips64_elf_fpregset_t fpregset64;
if (which == 0)
{
- if (core_reg_size != sizeof (gregset))
+ if (core_reg_size == sizeof (gregset))
{
- warning ("wrong size gregset struct in core file");
+ memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+ else if (core_reg_size == sizeof (gregset64))
+ {
+ memcpy ((char *) &gregset64, core_reg_sect, sizeof (gregset64));
+ mips64_supply_gregset (&gregset64);
}
else
{
- memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
- supply_gregset (&gregset);
+ warning ("wrong size gregset struct in core file");
}
}
else if (which == 2)
{
- if (core_reg_size != sizeof (fpregset))
+ if (core_reg_size == sizeof (fpregset))
{
- warning ("wrong size fpregset struct in core file");
+ memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
+ supply_fpregset (&fpregset);
+ }
+ else if (core_reg_size == sizeof (fpregset64))
+ {
+ memcpy ((char *) &fpregset64, core_reg_sect, sizeof (fpregset64));
+ mips64_supply_fpregset (&fpregset64);
}
else
{
- memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
- supply_fpregset (&fpregset);
+ warning ("wrong size fpregset struct in core file");
}
}
}
@@ -315,7 +615,7 @@ static struct core_fns regset_core_fns =
GDB that was built on a different host platform (for cross debugging). */
static struct link_map_offsets *
-mips_linux_svr4_fetch_link_map_offsets (void)
+mips64_linux_svr4_fetch_link_map_offsets (void)
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -324,40 +624,98 @@ mips_linux_svr4_fetch_link_map_offsets (
{
lmp = &lmo;
- lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
+ lmo.r_debug_size = 16; /* The actual size is 40 bytes, but
this is all we need. */
- lmo.r_map_offset = 4;
- lmo.r_map_size = 4;
+ lmo.r_map_offset = 8;
+ lmo.r_map_size = 8;
- lmo.link_map_size = 20;
+ lmo.link_map_size = 40;
lmo.l_addr_offset = 0;
- lmo.l_addr_size = 4;
+ lmo.l_addr_size = 8;
- lmo.l_name_offset = 4;
- lmo.l_name_size = 4;
+ lmo.l_name_offset = 8;
+ lmo.l_name_size = 8;
- lmo.l_next_offset = 12;
- lmo.l_next_size = 4;
+ lmo.l_next_offset = 24;
+ lmo.l_next_size = 8;
- lmo.l_prev_offset = 16;
- lmo.l_prev_size = 4;
+ lmo.l_prev_offset = 32;
+ lmo.l_prev_size = 8;
}
return lmp;
}
+/* Handle for obtaining pointer to the current register_addr() function
+ for a given architecture. */
+static struct gdbarch_data *register_addr_data;
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+ CORE_ADDR (*register_addr_ptr) (int, CORE_ADDR) =
+ gdbarch_data (current_gdbarch, register_addr_data);
+
+ gdb_assert (register_addr_ptr != 0);
+
+ return register_addr_ptr (regno, blockend);
+}
+
+static void
+set_mips_linux_register_addr (struct gdbarch *gdbarch,
+ CORE_ADDR (*register_addr_ptr) (int, CORE_ADDR))
+{
+ set_gdbarch_data (gdbarch, register_addr_data, register_addr_ptr);
+}
+
+static void *
+init_register_addr_data (struct gdbarch *gdbarch)
+{
+ return 0;
+}
+
static void
mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
- set_gdbarch_get_longjmp_target (gdbarch, mips_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, mips_linux_svr4_fetch_link_map_offsets);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum mips_abi abi = mips_abi (gdbarch);
+
+ switch (abi)
+ {
+ case MIPS_ABI_O32:
+ set_gdbarch_get_longjmp_target (gdbarch,
+ mips_linux_get_longjmp_target);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, mips_linux_svr4_fetch_link_map_offsets);
+ set_mips_linux_register_addr (gdbarch, mips_linux_register_addr);
+ break;
+ case MIPS_ABI_N32:
+ set_gdbarch_get_longjmp_target (gdbarch,
+ mips_linux_get_longjmp_target);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, mips_linux_svr4_fetch_link_map_offsets);
+ set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr);
+ break;
+ case MIPS_ABI_N64:
+ set_gdbarch_get_longjmp_target (gdbarch,
+ mips64_linux_get_longjmp_target);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, mips64_linux_svr4_fetch_link_map_offsets);
+ set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "can't handle ABI");
+ break;
+ }
}
void
_initialize_mips_linux_tdep (void)
{
+ register_addr_data =
+ register_gdbarch_data (init_register_addr_data, 0);
+
gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_LINUX,
mips_linux_init_abi);
add_core_fns (®set_core_fns);
Index: config/mips/linux64.mt
===================================================================
RCS file: config/mips/linux64.mt
diff -N config/mips/linux64.mt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/mips/linux64.mt 23 Dec 2002 22:35:29 -0000
@@ -0,0 +1,9 @@
+# Target: Linux/MIPS w/ support for 64-bit ABIs
+TDEPFILES= mips-tdep.o mips-linux-tdep.o corelow.o \
+ solib.o solib-svr4.o
+TM_FILE= tm-linux64.h
+
+GDBSERVER_DEPFILES = linux-low.o linux-mips-low.o reg-mips.o
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/mips/libsim.a
Index: config/mips/tm-linux64.h
===================================================================
RCS file: config/mips/tm-linux64.h
diff -N config/mips/tm-linux64.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/mips/tm-linux64.h 23 Dec 2002 22:35:29 -0000
@@ -0,0 +1,53 @@
+/* Target-dependent definitions for 64-bit GNU/Linux MIPS.
+
+ Copyright 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. */
+
+#ifndef TM_MIPS64LINUX_H
+#define TM_MIPS64LINUX_H
+
+#include "mips/tm-mips64.h"
+
+/* We don't want to inherit tm-mips.h's shared library trampoline code. */
+
+#undef IN_SOLIB_CALL_TRAMPOLINE
+#undef IN_SOLIB_RETURN_TRAMPOLINE
+#undef SKIP_TRAMPOLINE_CODE
+#undef IGNORE_HELPER_CALL
+
+/* GNU/Linux MIPS has __SIGRTMAX == 127. */
+
+#ifndef REALTIME_LO
+#define REALTIME_LO 32
+#define REALTIME_HI 128
+#endif
+
+#include "config/tm-linux.h"
+
+/* We do single stepping in software. */
+
+#define SOFTWARE_SINGLE_STEP_P() 1
+#define SOFTWARE_SINGLE_STEP(sig,bp_p) mips_software_single_step (sig, bp_p)
+
+/* FIXME: This still needs to be implemented. */
+
+#undef IN_SIGTRAMP
+#define IN_SIGTRAMP(pc, name) (0)
+
+#endif /* TM_MIPS64LINUX_H */
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Add support for 64-bit MIPS GNU/Linux targets
2002-12-23 15:07 [RFA] Add support for 64-bit MIPS GNU/Linux targets Kevin Buettner
@ 2002-12-23 16:01 ` Daniel Jacobowitz
2002-12-23 22:37 ` Kevin Buettner
2003-01-07 0:26 ` Andrew Cagney
0 siblings, 2 replies; 10+ messages in thread
From: Daniel Jacobowitz @ 2002-12-23 16:01 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
On Mon, Dec 23, 2002 at 03:50:22PM -0700, Kevin Buettner wrote:
> The patch below adds GNU/Linux specific support for the n32 and n64
> MIPS ABIs.
Great!
> I've been able to do both core file debugging and remote debugging
> using this patch when GDB is built as a cross debugger to a
> mips64-linux target. Unfortunately, I am not presently able to
> (completely) build a native mips64-linux debugger due to issues in
> other parts of the toolchain.
Right, I've heard about the problems. I'm breathlessly awaiting a
solution :)
> Okay to commit?
I have a couple of comments.
> @@ -95,15 +109,15 @@ supply_gregset (elf_gregset_t *gregsetp)
> memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
>
> for (regi = EF_REG0; regi <= EF_REG31; regi++)
> - supply_register ((regi - EF_REG0), (char *)(regp + regi));
> + supply_32bit_reg ((regi - EF_REG0), (char *)(regp + regi));
>
> - supply_register (LO_REGNUM, (char *)(regp + EF_LO));
> - supply_register (HI_REGNUM, (char *)(regp + EF_HI));
> + supply_32bit_reg (LO_REGNUM, (char *)(regp + EF_LO));
> + supply_32bit_reg (HI_REGNUM, (char *)(regp + EF_HI));
>
> - supply_register (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
> - supply_register (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
> - supply_register (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
> - supply_register (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
> + supply_32bit_reg (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
> + supply_32bit_reg (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
> + supply_32bit_reg (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
> + supply_32bit_reg (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
>
> /* Fill inaccessible registers with zero. */
> supply_register (UNUSED_REGNUM, zerobuf);
Correct me if I'm wrong, but native thread debugging isn't going to
work if you do this. proc-service.c calls supply_gregset directly and
everything blows up.
Is it time to multiarch supply_gregset?
> @@ -137,9 +151,8 @@ fill_gregset (elf_gregset_t *gregsetp, i
>
> if (regno < 32)
> {
> - src = &deprecated_registers[REGISTER_BYTE (regno)];
> dst = regp + regno + EF_REG0;
> - memcpy (dst, src, sizeof (elf_greg_t));
> + regcache_collect (regno, dst);
> return;
> }
>
Thanks, should have done this long ago.
> + set_mips_linux_register_addr (gdbarch, mips_linux_register_addr);
> void
> _initialize_mips_linux_tdep (void)
> {
> + register_addr_data =
> + register_gdbarch_data (init_register_addr_data, 0);
> +
> gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_LINUX,
> mips_linux_init_abi);
> add_core_fns (®set_core_fns);
Blech. So, the way _I_ would have done this would have been to put
this in the tdep structure. In fact I have several patches which add
similar methods to the tdep structure, for signal handling. Of course,
this is not compatible with the way Andrew asked to leave the tdep
struct in mips-tdep.c. This is OK for now, but hopefully we can get
rid of it eventually. We could multi-arch register_addr (is that
appropriate? It's a native-only function, isn't it?) to do that.
> Index: config/mips/linux64.mt
> ===================================================================
> RCS file: config/mips/linux64.mt
> diff -N config/mips/linux64.mt
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ config/mips/linux64.mt 23 Dec 2002 22:35:29 -0000
> @@ -0,0 +1,9 @@
> +# Target: Linux/MIPS w/ support for 64-bit ABIs
> +TDEPFILES= mips-tdep.o mips-linux-tdep.o corelow.o \
> + solib.o solib-svr4.o
> +TM_FILE= tm-linux64.h
> +
> +GDBSERVER_DEPFILES = linux-low.o linux-mips-low.o reg-mips.o
GDBSERVER_DEPFILES isn't actually used any more. I'll go through and
remove it from everywhere sometime soon; please don't introduce it.
> +
> +SIM_OBS = remote-sim.o
> +SIM = ../sim/mips/libsim.a
> Index: config/mips/tm-linux64.h
> ===================================================================
> RCS file: config/mips/tm-linux64.h
> diff -N config/mips/tm-linux64.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ config/mips/tm-linux64.h 23 Dec 2002 22:35:29 -0000
> @@ -0,0 +1,53 @@
> +/* Target-dependent definitions for 64-bit GNU/Linux MIPS.
> +
> + Copyright 2001, 2002 Free Software Foundation, Inc.
Should only say 2002. Also, this file could be replaced by:
#include "mips/tm-mips64.h"
#include "mips/tm-linux.h"
because of the way the include guards on tm-mips.h work. I think. If
that works, please do it that way. Hopefully I can kill this header
eventually; need to multi-arch solib handling, among other things.
So:
supply_gregset?
GDBSERVER_DEPFILES nit
tm-linux64 nit
Otherwise, this is OK.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Add support for 64-bit MIPS GNU/Linux targets
2002-12-23 16:01 ` Daniel Jacobowitz
@ 2002-12-23 22:37 ` Kevin Buettner
2002-12-24 9:25 ` Daniel Jacobowitz
2003-01-07 0:26 ` Andrew Cagney
1 sibling, 1 reply; 10+ messages in thread
From: Kevin Buettner @ 2002-12-23 22:37 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Dec 23, 6:56pm, Daniel Jacobowitz wrote:
> > @@ -95,15 +109,15 @@ supply_gregset (elf_gregset_t *gregsetp)
> > memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
> >
> > for (regi = EF_REG0; regi <= EF_REG31; regi++)
> > - supply_register ((regi - EF_REG0), (char *)(regp + regi));
> > + supply_32bit_reg ((regi - EF_REG0), (char *)(regp + regi));
> >
> > - supply_register (LO_REGNUM, (char *)(regp + EF_LO));
> > - supply_register (HI_REGNUM, (char *)(regp + EF_HI));
> > + supply_32bit_reg (LO_REGNUM, (char *)(regp + EF_LO));
> > + supply_32bit_reg (HI_REGNUM, (char *)(regp + EF_HI));
> >
> > - supply_register (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
> > - supply_register (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
> > - supply_register (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
> > - supply_register (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
> > + supply_32bit_reg (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
> > + supply_32bit_reg (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
> > + supply_32bit_reg (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
> > + supply_32bit_reg (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
> >
> > /* Fill inaccessible registers with zero. */
> > supply_register (UNUSED_REGNUM, zerobuf);
>
> Correct me if I'm wrong, but native thread debugging isn't going to
> work if you do this. proc-service.c calls supply_gregset directly and
> everything blows up.
True, but see below.
> Is it time to multiarch supply_gregset?
Maybe.
I've given this some thought and it seems to me that if we're going to
multiarch supply_gregset, we'll have to change its prototype; basically,
we'll have to pass gregsetp around as a void *. I'm not against this,
but I think it needs to be discussed first. (Also, either the regset
size or perhaps an allocation function will need to be provided using
a multiarch method.)
There are several other problems with native thread support on Linux/MIPS:
1) For o32, the core gregset layout is incompatible with that used for
threads. (The sizes of the arrays and the layouts are different.)
Hopefully this won't be a problem for n32 and n64.
2) There are actually three libthread_db.so libraries, one each for
o32, n32, and n64. Yet the gdb binary will (obviously) use only
one of these ABIs. It's not possible to dlopen() a library of
a differing ABI, which (unfortunately) means that a given gdb
binary can only provide thread support for only one ABI.
There are, of course, several technical options open to us to
work around this difficulty. One approach is to arrange for
each of these libraries to be built to use the ABI that gdb uses,
yet still know the details about the target ABI. Another is to
somehow combine the knowledge concerning the three ABIs into a
single libthread_db.so library. There may be other approaches
too, but at the moment, I don't think any of these solutions
will be trivial to implement (though some are clearly easier than
others).
Anyway, given all of the above it seems to me that native thread support
for Linux/MIPS which supports all three ABIs is quite a ways off.
[...]
> So:
> supply_gregset?
> GDBSERVER_DEPFILES nit
> tm-linux64 nit
>
> Otherwise, this is OK.
Thanks for the quick (but thorough) patch review!
I'll fix the GDBSERVER_DEPFILES and tm-linux64 nits, but the
supply_gregset issue will require further discussion. In the interim,
how would you like to proceed?
Kevin
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Add support for 64-bit MIPS GNU/Linux targets
2002-12-23 22:37 ` Kevin Buettner
@ 2002-12-24 9:25 ` Daniel Jacobowitz
2002-12-24 11:37 ` Kevin Buettner
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Jacobowitz @ 2002-12-24 9:25 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
On Mon, Dec 23, 2002 at 11:28:11PM -0700, Kevin Buettner wrote:
> On Dec 23, 6:56pm, Daniel Jacobowitz wrote:
>
> > > @@ -95,15 +109,15 @@ supply_gregset (elf_gregset_t *gregsetp)
> > > memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
> > >
> > > for (regi = EF_REG0; regi <= EF_REG31; regi++)
> > > - supply_register ((regi - EF_REG0), (char *)(regp + regi));
> > > + supply_32bit_reg ((regi - EF_REG0), (char *)(regp + regi));
> > >
> > > - supply_register (LO_REGNUM, (char *)(regp + EF_LO));
> > > - supply_register (HI_REGNUM, (char *)(regp + EF_HI));
> > > + supply_32bit_reg (LO_REGNUM, (char *)(regp + EF_LO));
> > > + supply_32bit_reg (HI_REGNUM, (char *)(regp + EF_HI));
> > >
> > > - supply_register (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
> > > - supply_register (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
> > > - supply_register (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
> > > - supply_register (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
> > > + supply_32bit_reg (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
> > > + supply_32bit_reg (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
> > > + supply_32bit_reg (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
> > > + supply_32bit_reg (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
> > >
> > > /* Fill inaccessible registers with zero. */
> > > supply_register (UNUSED_REGNUM, zerobuf);
> >
> > Correct me if I'm wrong, but native thread debugging isn't going to
> > work if you do this. proc-service.c calls supply_gregset directly and
> > everything blows up.
>
> True, but see below.
>
> > Is it time to multiarch supply_gregset?
>
> Maybe.
>
> I've given this some thought and it seems to me that if we're going to
> multiarch supply_gregset, we'll have to change its prototype; basically,
> we'll have to pass gregsetp around as a void *. I'm not against this,
> but I think it needs to be discussed first. (Also, either the regset
> size or perhaps an allocation function will need to be provided using
> a multiarch method.)
>
> There are several other problems with native thread support on Linux/MIPS:
>
> 1) For o32, the core gregset layout is incompatible with that used for
> threads. (The sizes of the arrays and the layouts are different.)
> Hopefully this won't be a problem for n32 and n64.
I don't believe that's currently true. Native thread support _works_
on O32; I spent a great deal of time nagging to get all the appropriate
gregsets corrected. You should find that a prgregset_t is just a
typedef to an elf_gregset_t in any recent (past six/eight months?)
glibc.
> 2) There are actually three libthread_db.so libraries, one each for
> o32, n32, and n64. Yet the gdb binary will (obviously) use only
> one of these ABIs. It's not possible to dlopen() a library of
> a differing ABI, which (unfortunately) means that a given gdb
> binary can only provide thread support for only one ABI.
>
> There are, of course, several technical options open to us to
> work around this difficulty. One approach is to arrange for
> each of these libraries to be built to use the ABI that gdb uses,
> yet still know the details about the target ABI. Another is to
> somehow combine the knowledge concerning the three ABIs into a
> single libthread_db.so library. There may be other approaches
> too, but at the moment, I don't think any of these solutions
> will be trivial to implement (though some are clearly easier than
> others).
Welcome to all the problems with the libthread_db.so model. Bugger.
Gdbserver will work, since it links to rather than dlopening
libthread_db, so one can simply provide gdbserver, gdbserver-n32, etc.
That's not ideal of course.
I don't know what can be done about this. I doubt libthread_db can
handle something for a different ABI and it'll be a royal pain to make
it do so.
>
> Anyway, given all of the above it seems to me that native thread support
> for Linux/MIPS which supports all three ABIs is quite a ways off.
>
> [...]
> > So:
> > supply_gregset?
> > GDBSERVER_DEPFILES nit
> > tm-linux64 nit
> >
> > Otherwise, this is OK.
>
> Thanks for the quick (but thorough) patch review!
>
> I'll fix the GDBSERVER_DEPFILES and tm-linux64 nits, but the
> supply_gregset issue will require further discussion. In the interim,
> how would you like to proceed?
Since it won't affect thread support for 32-bit MIPS, I've no objection
to committing it now.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Add support for 64-bit MIPS GNU/Linux targets
2002-12-24 9:25 ` Daniel Jacobowitz
@ 2002-12-24 11:37 ` Kevin Buettner
2002-12-24 12:09 ` Daniel Jacobowitz
0 siblings, 1 reply; 10+ messages in thread
From: Kevin Buettner @ 2002-12-24 11:37 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Dec 24, 9:53am, Daniel Jacobowitz wrote:
> > I'll fix the GDBSERVER_DEPFILES and tm-linux64 nits, but the
> > supply_gregset issue will require further discussion. In the interim,
> > how would you like to proceed?
>
> Since it won't affect thread support for 32-bit MIPS, I've no objection
> to committing it now.
Okay, it's in. In addition to fixing the problems previously discussed,
I found it necessary to change the osabi registration (in mips-linux-tdep.c)
from:
gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_LINUX,
mips_linux_init_abi);
to:
for (arch_info = bfd_lookup_arch (bfd_arch_mips, 0);
arch_info != NULL;
arch_info = arch_info->next)
{
gdbarch_register_osabi (bfd_arch_mips, arch_info->mach, GDB_OSABI_LINUX,
mips_linux_init_abi);
}
I'm not entirely happy with this change, but I see no way around it
due to the recent changes to osabi.c. (I'm open to suggestions for
better ways to do it...)
Kevin
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Add support for 64-bit MIPS GNU/Linux targets
2002-12-24 11:37 ` Kevin Buettner
@ 2002-12-24 12:09 ` Daniel Jacobowitz
2002-12-24 19:25 ` Kevin Buettner
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Jacobowitz @ 2002-12-24 12:09 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
On Tue, Dec 24, 2002 at 12:29:35PM -0700, Kevin Buettner wrote:
> On Dec 24, 9:53am, Daniel Jacobowitz wrote:
>
> > > I'll fix the GDBSERVER_DEPFILES and tm-linux64 nits, but the
> > > supply_gregset issue will require further discussion. In the interim,
> > > how would you like to proceed?
> >
> > Since it won't affect thread support for 32-bit MIPS, I've no objection
> > to committing it now.
>
> Okay, it's in. In addition to fixing the problems previously discussed,
> I found it necessary to change the osabi registration (in mips-linux-tdep.c)
> from:
>
> gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_LINUX,
> mips_linux_init_abi);
>
> to:
>
> for (arch_info = bfd_lookup_arch (bfd_arch_mips, 0);
> arch_info != NULL;
> arch_info = arch_info->next)
> {
> gdbarch_register_osabi (bfd_arch_mips, arch_info->mach, GDB_OSABI_LINUX,
> mips_linux_init_abi);
> }
>
> I'm not entirely happy with this change, but I see no way around it
> due to the recent changes to osabi.c. (I'm open to suggestions for
> better ways to do it...)
OK, that's a problem. In fact it's disgusting... A mach value of 0 is
always supposed to mean "default", if I remember my BFD correctly. Has
the change to pass a machine of 0 broken osabi support for anything
that sets a machine? It looks that way.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Add support for 64-bit MIPS GNU/Linux targets
2002-12-24 12:09 ` Daniel Jacobowitz
@ 2002-12-24 19:25 ` Kevin Buettner
0 siblings, 0 replies; 10+ messages in thread
From: Kevin Buettner @ 2002-12-24 19:25 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Dec 24, 2:40pm, Daniel Jacobowitz wrote:
[...]
> > I found it necessary to change the osabi registration (in mips-linux-tdep.c)
> > from:
> >
> > gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_LINUX,
> > mips_linux_init_abi);
> >
> > to:
> >
> > for (arch_info = bfd_lookup_arch (bfd_arch_mips, 0);
> > arch_info != NULL;
> > arch_info = arch_info->next)
> > {
> > gdbarch_register_osabi (bfd_arch_mips, arch_info->mach, GDB_OSABI_LINUX,
> > mips_linux_init_abi);
> > }
> >
> > I'm not entirely happy with this change, but I see no way around it
> > due to the recent changes to osabi.c. (I'm open to suggestions for
> > better ways to do it...)
>
> OK, that's a problem. In fact it's disgusting... A mach value of 0 is
> always supposed to mean "default", if I remember my BFD correctly. Has
> the change to pass a machine of 0 broken osabi support for anything
> that sets a machine? It looks that way.
I wonder if Mark made a mistake in his recent change to gdbarch_init_osabi(),
specifically in the following code:
for (handler = gdb_osabi_handler_list; handler != NULL;
handler = handler->next)
{
if (handler->osabi != osabi)
continue;
/* Check whether the machine type and architecture of the
handler are compatible with the desired machine type and
architecture.
NOTE: kettenis/20021027: There may be more than one machine
type that is compatible with the desired machine type. Right
now we simply return the first match, which is fine for now.
However, we might want to do something smarter in the future. */
compatible = arch_info->compatible (arch_info, handler->arch_info);
if (compatible == handler->arch_info)
{
(*handler->init_osabi) (info, gdbarch);
return;
}
}
For MIPS, the compatible() function is defined as follows:
static const bfd_arch_info_type *
mips_compatible (a, b)
const bfd_arch_info_type *a;
const bfd_arch_info_type *b;
{
if (a->arch != b->arch)
return NULL;
/* Machine compatibility is checked in
_bfd_mips_elf_merge_private_bfd_data. */
return a;
}
So... the first argument is returned when the ``arch'' fields are the
same, and NULL otherwise. Thus, for MIPS, the following bit of
code:
compatible = arch_info->compatible (arch_info, handler->arch_info);
if (compatible == handler->arch_info)
...
means the same as:
if (arch_info == handler->arch_info)
...
which seems overly restrictive and not at all in the spirit of the
comment preceding that bit of code.
Kevin
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Add support for 64-bit MIPS GNU/Linux targets
2002-12-23 16:01 ` Daniel Jacobowitz
2002-12-23 22:37 ` Kevin Buettner
@ 2003-01-07 0:26 ` Andrew Cagney
2003-01-07 23:16 ` Daniel Jacobowitz
1 sibling, 1 reply; 10+ messages in thread
From: Andrew Cagney @ 2003-01-07 0:26 UTC (permalink / raw)
To: Daniel Jacobowitz, Kevin Buettner; +Cc: gdb-patches
> + register_addr_data =
>> + register_gdbarch_data (init_register_addr_data, 0);
>> +
>> gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_LINUX,
>> mips_linux_init_abi);
>> add_core_fns (®set_core_fns);
>
>
> Blech. So, the way _I_ would have done this would have been to put
> this in the tdep structure. In fact I have several patches which add
> similar methods to the tdep structure, for signal handling. Of course,
> this is not compatible with the way Andrew asked to leave the tdep
> struct in mips-tdep.c. This is OK for now, but hopefully we can get
> rid of it eventually. We could multi-arch register_addr (is that
> appropriate? It's a native-only function, isn't it?) to do that.
>
Using the gdbarch data mechanism is a good idea - it keeps that
architecture dependency local to that file. It definitly doesn't belong
in the tdep structure since nothing, other than this file, needs it.
Hmm, should the actual code live in mips-linux-nat.c though?
enjoy,
Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Add support for 64-bit MIPS GNU/Linux targets
2003-01-07 0:26 ` Andrew Cagney
@ 2003-01-07 23:16 ` Daniel Jacobowitz
2003-01-08 0:00 ` Andrew Cagney
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Jacobowitz @ 2003-01-07 23:16 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Kevin Buettner, gdb-patches
On Mon, Jan 06, 2003 at 07:24:35PM -0500, Andrew Cagney wrote:
> >+ register_addr_data =
> >>+ register_gdbarch_data (init_register_addr_data, 0);
> >>+
> >> gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_LINUX,
> >> mips_linux_init_abi);
> >> add_core_fns (®set_core_fns);
> >
> >
> >Blech. So, the way _I_ would have done this would have been to put
> >this in the tdep structure. In fact I have several patches which add
> >similar methods to the tdep structure, for signal handling. Of course,
> >this is not compatible with the way Andrew asked to leave the tdep
> >struct in mips-tdep.c. This is OK for now, but hopefully we can get
> >rid of it eventually. We could multi-arch register_addr (is that
> >appropriate? It's a native-only function, isn't it?) to do that.
> >
>
> Using the gdbarch data mechanism is a good idea - it keeps that
> architecture dependency local to that file. It definitly doesn't belong
> in the tdep structure since nothing, other than this file, needs it.
>
> Hmm, should the actual code live in mips-linux-nat.c though?
Well, here's the situation: other files call register_addr. I think
core-regset? It's a native only method, but which one we want depends
on the current gdbarch. I suppose we can just use a gdbarch_data to
handle this, but it seems as if there should be a better way. Should
it be properly multi-arched (is there any point?)?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFA] Add support for 64-bit MIPS GNU/Linux targets
2003-01-07 23:16 ` Daniel Jacobowitz
@ 2003-01-08 0:00 ` Andrew Cagney
0 siblings, 0 replies; 10+ messages in thread
From: Andrew Cagney @ 2003-01-08 0:00 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Kevin Buettner, gdb-patches
> On Mon, Jan 06, 2003 at 07:24:35PM -0500, Andrew Cagney wrote:
>
>> >+ register_addr_data =
>
>> >>+ register_gdbarch_data (init_register_addr_data, 0);
>> >>+
>> >> gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_LINUX,
>> >> mips_linux_init_abi);
>> >> add_core_fns (®set_core_fns);
>
>> >
>> >
>> >Blech. So, the way _I_ would have done this would have been to put
>> >this in the tdep structure. In fact I have several patches which add
>> >similar methods to the tdep structure, for signal handling. Of course,
>> >this is not compatible with the way Andrew asked to leave the tdep
>> >struct in mips-tdep.c. This is OK for now, but hopefully we can get
>> >rid of it eventually. We could multi-arch register_addr (is that
>> >appropriate? It's a native-only function, isn't it?) to do that.
>> >
>
>>
>> Using the gdbarch data mechanism is a good idea - it keeps that
>> architecture dependency local to that file. It definitly doesn't belong
>> in the tdep structure since nothing, other than this file, needs it.
>>
>> Hmm, should the actual code live in mips-linux-nat.c though?
>
>
> Well, here's the situation: other files call register_addr. I think
> core-regset? It's a native only method, but which one we want depends
> on the current gdbarch. I suppose we can just use a gdbarch_data to
> handle this, but it seems as if there should be a better way. Should
> it be properly multi-arched (is there any point?)?
The method register_addr() is a static interface between the nat code
and the ptrace code, not the core of GDB and the ISA/ABI. Hence, it
doesn't belong in the architecture vector (which is for interfaces
between the latter two).
As for implementation, there are two choices:
- as kevin did
- as a function that contains a switch to handle the specific cases
That leaves the question, should the function live in mips-linux-nat.c?
Andrew
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2003-01-08 0:00 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-23 15:07 [RFA] Add support for 64-bit MIPS GNU/Linux targets Kevin Buettner
2002-12-23 16:01 ` Daniel Jacobowitz
2002-12-23 22:37 ` Kevin Buettner
2002-12-24 9:25 ` Daniel Jacobowitz
2002-12-24 11:37 ` Kevin Buettner
2002-12-24 12:09 ` Daniel Jacobowitz
2002-12-24 19:25 ` Kevin Buettner
2003-01-07 0:26 ` Andrew Cagney
2003-01-07 23:16 ` Daniel Jacobowitz
2003-01-08 0:00 ` Andrew Cagney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox