From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29062 invoked by alias); 15 Oct 2009 16:20:16 -0000 Received: (qmail 29041 invoked by uid 22791); 15 Oct 2009 16:20:13 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 15 Oct 2009 16:20:05 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id A3FAC2BACAA; Thu, 15 Oct 2009 12:20:03 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id ELZbPQnIhtjk; Thu, 15 Oct 2009 12:20:03 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 729B22BACA1; Thu, 15 Oct 2009 12:20:01 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 550C4F58A0; Thu, 15 Oct 2009 09:19:50 -0700 (PDT) Date: Thu, 15 Oct 2009 16:20:00 -0000 From: Joel Brobecker To: Andrew Stubbs Cc: gdb-patches@sources.redhat.com Subject: Re: [PATCH][SH] Implement core-file support for sh-linux Message-ID: <20091015161950.GZ5272@adacore.com> References: <4AD33C69.2070301@codesourcery.com> <20091014045558.GT5272@adacore.com> <4AD7233E.9050906@codesourcery.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="ReaqsoxgOBHFXBhH" Content-Disposition: inline In-Reply-To: <4AD7233E.9050906@codesourcery.com> User-Agent: Mutt/1.5.18 (2008-05-17) Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-10/txt/msg00334.txt.bz2 --ReaqsoxgOBHFXBhH Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1442 >> Then the code from shnbsd can be moved to sh-tdep.c and the only >> remaining bit is to initialize the array appropriately in shbnsd-tdep >> and sh-linux-tdep. > > I believe this patch should do what you suggest. You definitely got the idea, but the implementation does not work in the case of multi-arch debugging. This is because you are introducing a global variable. The solution is to rely on the gdbarch_tdep structure. Here is a patch that should provide you with a quick sketch of how you can implement this: - I created a gdbarch_tdep structure for SH, since it didn't need one before; I populated it with a simple regmap being an array of integers, but it appears that this may not be sufficient, since registers might not be stored in the same order as GDB register numbers. So your slightly more complex structure might be required - Move the core-file support from shnbsd-tdep to sh-tdep, did some renaming - hopefully I didn't miss much - Initialized support for core-file in sh-tdep knowing that the routine that checks core file section names will only return non-NULL if such support is available (detected by looking at the gdbarch_tdep structure). Hopefully, once this is in place, the only thing you should have left to do is to create the offset maps in sh-linux-tdep and set the tdep maps during the sh/linux gdbarch initialization. Does this make sense to you? -- Joel --ReaqsoxgOBHFXBhH Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="sh-core.diff" Content-length: 9363 diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c index 46aad1d..5eba796 100644 --- a/gdb/sh-linux-tdep.c +++ b/gdb/sh-linux-tdep.c @@ -28,6 +28,8 @@ static void sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* GNU/Linux uses SVR4-style shared libraries. */ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); set_solib_svr4_fetch_link_map_offsets @@ -36,6 +38,12 @@ sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); + + /* Core files are supported for 32-bit SH only, at present. */ + if (info.bfd_arch_info->mach != bfd_mach_sh5) + { + /* set tdep->core_regmap and tdep->core_fpregmap here. */ + } } /* Provide a prototype to silence -Wmissing-prototypes. */ diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index 3e509bf..5d8d5a3 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -2740,6 +2740,102 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) } +/* Supply register REGNUM from the buffer specified by GREGS and LEN + in the general-purpose register set REGSET to register cache + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ + +static void +sh_supply_gregset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Use the tdep data to fill in the regset. */ +} + +/* Collect register REGNUM in the general-purpose register set + REGSET. from register cache REGCACHE into the buffer specified by + GREGS and LEN. If REGNUM is -1, do this for all registers in + REGSET. */ + +static void +sh_collect_gregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *gregs, size_t len) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int i; + + /* Use the tdep data to fill in the regset. */ +} + +/* SH register sets. */ + +static struct regset sh_gregset = +{ + NULL, + sh_supply_gregset, + sh_collect_gregset +}; + +/* Supply register REGNUM from the buffer specified by FPREGS and LEN + in the floating point register set REGSET to register cache + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ + +static void +sh_supply_fpregset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *fpregs, size_t len) +{ + /* Same as above. */ +} + +/* Collect register REGNUM in the floating point register set + REGSET. from register cache REGCACHE into the buffer specified by + FPREGS and LEN. If REGNUM is -1, do this for all registers in + REGSET. */ + +static void +sh_collect_fpregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *fpregs, size_t len) +{ + /* Same as above. */ +} + +/* SH register sets. */ + +static struct regset sh_fpregset = +{ + NULL, + sh_supply_fpregset, + sh_collect_fpregset +}; + +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ + +static const struct regset * +sh_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, + size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (tdep->core_regmap == NULL) + return NULL; /* core files not supported on this architecture. */ + + if (strcmp (sect_name, ".reg") == 0 && sect_size >= SH_SIZEOF_GREGS) + return &sh_gregset; + + if (tdep->core_fp_regmap + && strcmp (sect_name, ".reg2") == 0 + && sect_size >= SH_SIZEOF_FP_GREGS) + return &sh_fpregset; + + return NULL; +} + static struct gdbarch * sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { @@ -2803,7 +2899,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* None found, create a new architecture from the information provided. */ - gdbarch = gdbarch_alloc (&info, NULL); + tdep = XZALLOC (struct gdbarch_tdep); + gdbarch = gdbarch_alloc (&info, tdep); set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT); @@ -2847,6 +2944,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) dwarf2_frame_set_init_reg (gdbarch, sh_dwarf2_frame_init_reg); + set_gdbarch_regset_from_core_section (gdbarch, sh_regset_from_core_section); + switch (info.bfd_arch_info->mach) { case bfd_mach_sh: diff --git a/gdb/sh-tdep.h b/gdb/sh-tdep.h index dfa928e..37a8f8c 100644 --- a/gdb/sh-tdep.h +++ b/gdb/sh-tdep.h @@ -82,6 +82,18 @@ enum FV_LAST_REGNUM = 79 }; +struct gdbarch_tdep +{ + /* Non-NULL when debugging from a core file. Provides the offset + where each general-purpose register is stored inside the associated + core file section. */ + int *core_regmap; + /* Non-NULL when debugging from a core file and when FP registers are + available. Provides the offset where each FP register is stored + inside the associated core file section. */ + int *core_fp_regmap; +}; + extern gdbarch_init_ftype sh64_gdbarch_init; extern void sh64_show_regs (struct frame_info *); diff --git a/gdb/shnbsd-tdep.c b/gdb/shnbsd-tdep.c index a0cddc5..633770d 100644 --- a/gdb/shnbsd-tdep.c +++ b/gdb/shnbsd-tdep.c @@ -59,105 +59,6 @@ static const int regmap[] = /* Sizeof `struct reg' in . */ #define SHNBSD_SIZEOF_GREGS (21 * 4) -/* Supply register REGNUM from the buffer specified by GREGS and LEN - in the general-purpose register set REGSET to register cache - REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ - -static void -shnbsd_supply_gregset (const struct regset *regset, - struct regcache *regcache, - int regnum, const void *gregs, size_t len) -{ - struct gdbarch *gdbarch = get_regcache_arch (regcache); - const gdb_byte *regs = gregs; - int i; - - gdb_assert (len >= SHNBSD_SIZEOF_GREGS); - - if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1) - regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), - regs + (0 * 4)); - - if (regnum == SR_REGNUM || regnum == -1) - regcache_raw_supply (regcache, SR_REGNUM, regs + (1 * 4)); - - if (regnum == PR_REGNUM || regnum == -1) - regcache_raw_supply (regcache, PR_REGNUM, regs + (2 * 4)); - - if (regnum == MACH_REGNUM || regnum == -1) - regcache_raw_supply (regcache, MACH_REGNUM, regs + (3 * 4)); - - if (regnum == MACL_REGNUM || regnum == -1) - regcache_raw_supply (regcache, MACL_REGNUM, regs + (4 * 4)); - - for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++) - { - if (regnum == i || regnum == -1) - regcache_raw_supply (regcache, i, regs + regmap[i - R0_REGNUM]); - } -} - -/* Collect register REGNUM in the general-purpose register set - REGSET. from register cache REGCACHE into the buffer specified by - GREGS and LEN. If REGNUM is -1, do this for all registers in - REGSET. */ - -static void -shnbsd_collect_gregset (const struct regset *regset, - const struct regcache *regcache, - int regnum, void *gregs, size_t len) -{ - struct gdbarch *gdbarch = get_regcache_arch (regcache); - gdb_byte *regs = gregs; - int i; - - gdb_assert (len >= SHNBSD_SIZEOF_GREGS); - - if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1) - regcache_raw_collect (regcache, gdbarch_pc_regnum (gdbarch), - regs + (0 * 4)); - - if (regnum == SR_REGNUM || regnum == -1) - regcache_raw_collect (regcache, SR_REGNUM, regs + (1 * 4)); - - if (regnum == PR_REGNUM || regnum == -1) - regcache_raw_collect (regcache, PR_REGNUM, regs + (2 * 4)); - - if (regnum == MACH_REGNUM || regnum == -1) - regcache_raw_collect (regcache, MACH_REGNUM, regs + (3 * 4)); - - if (regnum == MACL_REGNUM || regnum == -1) - regcache_raw_collect (regcache, MACL_REGNUM, regs + (4 * 4)); - - for (i = R0_REGNUM; i <= (R0_REGNUM + 15); i++) - { - if (regnum == i || regnum == -1) - regcache_raw_collect (regcache, i, regs + regmap[i - R0_REGNUM]); - } -} - -/* SH register sets. */ - -static struct regset shnbsd_gregset = -{ - NULL, - shnbsd_supply_gregset, - shnbsd_collect_gregset -}; - -/* Return the appropriate register set for the core section identified - by SECT_NAME and SECT_SIZE. */ - -static const struct regset * -shnbsd_regset_from_core_section (struct gdbarch *gdbarch, - const char *sect_name, size_t sect_size) -{ - if (strcmp (sect_name, ".reg") == 0 && sect_size >= SHNBSD_SIZEOF_GREGS) - return &shnbsd_gregset; - - return NULL; -} - void shnbsd_supply_reg (struct regcache *regcache, const char *regs, int regnum) { @@ -177,11 +78,12 @@ static void shnbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { - set_gdbarch_regset_from_core_section - (gdbarch, shnbsd_regset_from_core_section); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); + + /* Set tdep->core_regmap here. */ } --ReaqsoxgOBHFXBhH--