From 23e049712dca23855caea20f302a64039360e381 Mon Sep 17 00:00:00 2001 From: Michael Snyder Date: Wed, 30 Aug 2000 00:58:58 +0000 Subject: [PATCH] 2000-08-29 Michael Snyder * valops.c (value_cast): Indentation fix-up. * acconfig.h (HAVE_PRGREGSET32_T, HAVE_PRFPREGSET32_T, HAVE_STRUCT_LINK_MAP32): New configure macros. * config.in: Ditto. * configure.in: Test for the above new macros. * breakpoint.c: Update copyright date. * core-sol2.c: Include v9/sys/privregs.h directly to work around a bug in Sun's Solaris 8 header files. (fetch_core_registers): Use the above new configure macros to handle cross-debugging of 32-bit core files on a 64-bit host. * sol-thread.c (ps_pdmodel) New function. (rw_common): For debugging of 32-bit apps on a 64-bit host, truncate addresses to 32 bits. * solib.c (solib_extract_address): Functionize. Make 32/64 aware. (LM_ADDR, LM_NEXT, LM_NAME): Ditto. (IGNORE_FIRST_LINK_MAP): Ditto. (first_link_map_member): Make 32/64 aware. (open_symbol_file_object): Ditto. (current_sos): Ditto. --- gdb/ChangeLog | 22 +++++ gdb/acconfig.h | 9 +++ gdb/breakpoint.c | 2 +- gdb/config.in | 9 +++ gdb/configure.in | 23 ++++++ gdb/core-sol2.c | 66 +++++++++++++-- gdb/sol-thread.c | 29 ++++++- gdb/solib.c | 207 ++++++++++++++++++++++++++++++++++++++++------- gdb/valops.c | 4 +- 9 files changed, 330 insertions(+), 41 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 500c9383d3..c7360e1ef6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2000-08-29 Michael Snyder + + * valops.c (value_cast): Indentation fix-up. + * acconfig.h (HAVE_PRGREGSET32_T, HAVE_PRFPREGSET32_T, + HAVE_STRUCT_LINK_MAP32): New configure macros. + * config.in: Ditto. + * configure.in: Test for the above new macros. + * breakpoint.c: Update copyright date. + * core-sol2.c: Include v9/sys/privregs.h directly to + work around a bug in Sun's Solaris 8 header files. + (fetch_core_registers): Use the above new configure macros to + handle cross-debugging of 32-bit core files on a 64-bit host. + * sol-thread.c (ps_pdmodel) New function. + (rw_common): For debugging of 32-bit apps on a 64-bit host, + truncate addresses to 32 bits. + * solib.c (solib_extract_address): Functionize. Make 32/64 aware. + (LM_ADDR, LM_NEXT, LM_NAME): Ditto. + (IGNORE_FIRST_LINK_MAP): Ditto. + (first_link_map_member): Make 32/64 aware. + (open_symbol_file_object): Ditto. + (current_sos): Ditto. + 2000-08-29 Michael Snyder * i386-linux-nat.c (i386_linux_skip_solib_resolver, diff --git a/gdb/acconfig.h b/gdb/acconfig.h index fea655c899..ba09e8131b 100644 --- a/gdb/acconfig.h +++ b/gdb/acconfig.h @@ -31,6 +31,15 @@ /* Define if has psaddr_t. */ #undef HAVE_PSADDR_T +/* Define if has prgregset32_t. */ +#undef HAVE_PRGREGSET32_T + +/* Define if has prfpregset32_t. */ +#undef HAVE_PRFPREGSET32_T + +/* Define if has struct link_map32 */ +#undef HAVE_STRUCT_LINK_MAP32 + /* Define if the prfpregset_t type is broken. */ #undef PRFPREGSET_T_BROKEN diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 463337399d..489aad2ee9 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1,5 +1,5 @@ /* Everything about breakpoints, for GDB. - Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999 + Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999, 2000 Free Software Foundation, Inc. This file is part of GDB. diff --git a/gdb/config.in b/gdb/config.in index bbeebbeb9f..e86239c2cc 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -246,6 +246,9 @@ /* Define if you have the header file. */ #undef HAVE_LINK_H +/* Define if defines struct link_map32. */ +#undef HAVE_STRUCT_LINK_MAP32 + /* Define if you have the header file. */ #undef HAVE_LOCALE_H @@ -417,6 +420,12 @@ /* Define if has prfpregset_t. */ #undef HAVE_PRFPREGSET_T +/* Define if has prgregset32_t. */ +#undef HAVE_PRGREGSET32_T + +/* Define if has prfpregset32_t. */ +#undef HAVE_PRFPREGSET32_T + /* Define if has lwpid_t. */ #undef HAVE_LWPID_T diff --git a/gdb/configure.in b/gdb/configure.in index 6dfd7f1f6b..6dda43ab44 100644 --- a/gdb/configure.in +++ b/gdb/configure.in @@ -229,9 +229,32 @@ if test "$ac_cv_header_sys_procfs_h" = yes; then BFD_HAVE_SYS_PROCFS_TYPE(fpregset_t) BFD_HAVE_SYS_PROCFS_TYPE(prgregset_t) BFD_HAVE_SYS_PROCFS_TYPE(prfpregset_t) + BFD_HAVE_SYS_PROCFS_TYPE(prgregset32_t) + BFD_HAVE_SYS_PROCFS_TYPE(prfpregset32_t) BFD_HAVE_SYS_PROCFS_TYPE(lwpid_t) BFD_HAVE_SYS_PROCFS_TYPE(psaddr_t) + dnl Check for struct link_map32 type, which allows a 64-bit Solaris + dnl debugger to debug a 32-bit Solaris app with 32-bit shared libraries. + + AC_MSG_CHECKING(for struct link_map32 in sys/link.h) + AC_CACHE_VAL(gdb_cv_have_struct_link_map32, + [AC_TRY_RUN([#define _SYSCALL32 + #include + int main() + { + if (sizeof (struct link_map32) > 0) + return 1; + return 0; + }], + gdb_cv_have_struct_link_map32=no, + gdb_cv_have_struct_link_map32=yes, + gdb_cv_have_struct_link_map32=yes)]) + AC_MSG_RESULT($gdb_cv_have_struct_link_map32) + if test $gdb_cv_have_struct_link_map32 = yes; then + AC_DEFINE(HAVE_STRUCT_LINK_MAP32) + fi + dnl Check for broken prfpregset_t type dnl For Linux/i386, glibc 2.1.3 was released with a bogus diff --git a/gdb/core-sol2.c b/gdb/core-sol2.c index 59aab7bbfd..5a32c041b8 100644 --- a/gdb/core-sol2.c +++ b/gdb/core-sol2.c @@ -1,5 +1,5 @@ /* Machine independent support for Solaris 2 core files for GDB. - Copyright 1994 Free Software Foundation, Inc. + Copyright 1994, 2000 Free Software Foundation, Inc. This file is part of GDB. @@ -26,7 +26,15 @@ This file combines the core register fetching from core-regset.c and sparc-nat.c to be able to read both flavours. */ +/* for Sparc64 cross Sparc32 */ +#define _SYSCALL32 #include "defs.h" + +#if defined (__sparcv9) +/* Fails to get included by the Solaris system header files. */ +# include +#endif + #include #include #include @@ -55,19 +63,36 @@ static void fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, CORE_ADDR reg_addr) { - prgregset_t prgregset; - prfpregset_t prfpregset; + int i; if (which == 0) { - if (core_reg_size == sizeof (prgregset)) + prgregset_t prgregset; + + if (core_reg_size == sizeof (prgregset_t)) { memcpy ((char *) &prgregset, core_reg_sect, sizeof (prgregset)); supply_gregset (&prgregset); } +#if defined (HAVE_PRGREGSET32_T) + /* 32-bit corefile, 64-bit debugger. */ + else if (core_reg_size == sizeof (prgregset32_t)) + { + prgreg32_t *core_gregs; + + /* Can't use memcpy here, because the core file contains + 32-bit regs; supply_register expects 64-bit regs. */ + core_gregs = (prgreg32_t *) core_reg_sect; + for (i = 0; i < NPRGREG; i++) + prgregset[i] = core_gregs[i]; + + supply_gregset (&prgregset); + } +#endif /* HAVE_PRGREGSET32_T */ else if (core_reg_size == sizeof (struct regs)) { -#define gregs ((struct regs *)core_reg_sect) + struct regs *gregs = (struct regs *) core_reg_sect; + /* G0 *always* holds 0. */ *(int *) ®isters[REGISTER_BYTE (0)] = 0; @@ -103,14 +128,41 @@ fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, } else if (which == 2) { - if (core_reg_size == sizeof (prfpregset)) + prfpregset_t prfpregset; + + if (core_reg_size == sizeof (prfpregset_t)) { memcpy ((char *) &prfpregset, core_reg_sect, sizeof (prfpregset)); supply_fpregset (&prfpregset); } +#if defined (HAVE_PRFPREGSET32_T) + /* 32-bit corefile, 64-bit debugger. */ + else if (core_reg_size == sizeof (prfpregset32_t)) + { + prfpregset32_t *core_fpregset; + + /* Can't use memcpy here, because the core file contains + 32-bit regs; supply_fpregset expects 64-bit regs. */ + + core_fpregset = (prfpregset32_t *) core_reg_sect; + for (i = 0; i < 16; i++) + prfpregset.pr_fr.pr_dregs[i] = core_fpregset->pr_fr.pr_dregs[i]; + while (i < 32) + prfpregset.pr_fr.pr_dregs[i++] = 0; + + prfpregset.pr_fsr = core_fpregset->pr_fsr; + prfpregset.pr_qcnt = core_fpregset->pr_qcnt; + prfpregset.pr_q_entrysize = core_fpregset->pr_q_entrysize; + prfpregset.pr_en = core_fpregset->pr_en; + /* We will not use the pr_q array. */ + + supply_fpregset (&prfpregset); + } +#endif /* HAVE_PRFPREGSET32_T */ else if (core_reg_size >= sizeof (struct fpu)) { -#define fpuregs ((struct fpu *) core_reg_sect) + struct fpu *fpuregs = (struct fpu *) core_reg_sect; + memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], &fpuregs->fpu_fr, sizeof (fpuregs->fpu_fr)); memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr, diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c index 0ddeb2666b..3e5014e4ac 100644 --- a/gdb/sol-thread.c +++ b/gdb/sol-thread.c @@ -1,5 +1,5 @@ /* Low level interface for debugging Solaris threads for GDB, the GNU debugger. - Copyright 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc. This file is part of GDB. @@ -57,6 +57,7 @@ #include #include #include "gdbcmd.h" +#include "gdbcore.h" extern struct target_ops sol_thread_ops; /* Forward declaration */ extern struct target_ops sol_core_ops; /* Forward declaration */ @@ -1044,6 +1045,13 @@ rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr, inferior_pid = procfs_first_available (); /* Find any live lwp. */ /* Note: don't need to call switch_to_thread; we're just reading memory. */ +#if defined (__sparcv9) + /* For Sparc64 cross Sparc32, make sure the address has not been + accidentally sign-extended (or whatever) to beyond 32 bits. */ + if (bfd_elf_get_arch_size (exec_bfd) == 32) + addr &= 0xffffffff; +#endif + while (size > 0) { int cc; @@ -1301,6 +1309,25 @@ ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, return PS_OK; } +/* Identify process as 32-bit or 64-bit. + At the moment I'm using bfd to do this. + There might be a more solaris-specific (eg. procfs) method, + but this ought to work. */ + +ps_err_e +ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model) +{ + if (exec_bfd == 0) + return PS_ERR; + + if (bfd_elf_get_arch_size (exec_bfd) == 32) + *data_model = PR_MODEL_ILP32; + else + *data_model = PR_MODEL_LP64; + + return PS_OK; +} + #ifdef TM_I386SOL2_H /* Reads the local descriptor table of a LWP. */ diff --git a/gdb/solib.c b/gdb/solib.c index d83c95ada4..1a725a5429 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#define _SYSCALL32 /* for Sparc64 cross Sparc32 */ #include "defs.h" /* This file is only compilable if link.h is available. */ @@ -107,24 +107,33 @@ static char *main_name_list[] = NULL }; -/* local data declarations */ - -/* Macro to extract an address from a solib structure. +/* Function to extract an address from a solib structure. When GDB is configured for some 32-bit targets (e.g. Solaris 2.7 sparc), BFD is configured to handle 64-bit targets, so CORE_ADDR is 64 bits. We have to extract only the significant bits of addresses - to get the right address when accessing the core file BFD. */ + to get the right address when accessing the core file BFD. -#define SOLIB_EXTRACT_ADDRESS(member) \ - extract_address (&member, sizeof (member)) + We'll use the BFD itself to determine the number of significant bits. + MVS, June 2000 */ + +static CORE_ADDR +solib_extract_address (void *memberp) +{ + return extract_address (memberp, + bfd_elf_get_arch_size (exec_bfd) / 8); +} + +#define SOLIB_EXTRACT_ADDRESS(MEMBER) \ + solib_extract_address (&MEMBER) + +/* local data declarations */ #ifndef SVR4_SHARED_LIBS -#define LM_ADDR(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.lm_addr)) -#define LM_NEXT(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.lm_next)) -#define LM_NAME(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.lm_name)) -/* Test for first link map entry; first entry is a shared library. */ -#define IGNORE_FIRST_LINK_MAP_ENTRY(so) (0) +/* NOTE: converted the macros LM_ADDR, LM_NEXT, LM_NAME and + IGNORE_FIRST_LINK_MAP_ENTRY into functions (see below). + MVS, June 2000 */ + static struct link_dynamic dynamic_copy; static struct link_dynamic_2 ld_2_copy; static struct ld_debug debug_copy; @@ -133,13 +142,11 @@ static CORE_ADDR flag_addr; #else /* SVR4_SHARED_LIBS */ -#define LM_ADDR(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_addr)) -#define LM_NEXT(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_next)) -#define LM_NAME(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_name)) -/* Test for first link map entry; first entry is the exec-file. */ -#define IGNORE_FIRST_LINK_MAP_ENTRY(so) \ - (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_prev) == 0) static struct r_debug debug_copy; +#if defined (HAVE_STRUCT_LINK_MAP32) +static struct r_debug32 debug32_copy; /* Sparc64 cross Sparc32 */ +#endif + char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */ #endif /* !SVR4_SHARED_LIBS */ @@ -152,6 +159,9 @@ struct so_list struct so_list *next; /* next structure in linked list */ struct link_map lm; /* copy of link map from inferior */ +#if defined (HAVE_STRUCT_LINK_MAP32) + struct link_map32 lm32; /* copy of link map from 32-bit inferior */ +#endif CORE_ADDR lmaddr; /* addr in inferior lm was read from */ /* Shared object file name, exactly as it appears in the @@ -179,6 +189,107 @@ struct so_list }; static struct so_list *so_list_head; /* List of known shared objects */ + +/* link map access functions */ + +#ifndef SVR4_SHARED_LIBS + +static CORE_ADDR +LM_ADDR (so) + struct so_list *so; +{ +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + return extract_address (&so->lm32.lm_addr, sizeof (so->lm32.lm_addr)); + else +#endif + return extract_address (&so->lm.lm_addr, sizeof (so->lm.lm_addr)); +} + +static CORE_ADDR +LM_NEXT (so) + struct so_list *so; +{ +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + return extract_address (&so->lm32.lm_next, sizeof (so->lm32.lm_next)); + else +#endif + return extract_address (&so->lm.lm_next, sizeof (so->lm.lm_next)); +} + +static CORE_ADDR +LM_NAME (so) + struct so_list *so; +{ +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + return extract_address (&so->lm32.lm_name, sizeof (so->lm32.lm_name)); + else +#endif + return extract_address (&so->lm.lm_name, sizeof (so->lm.lm_name)); +} + +static int +IGNORE_FIRST_LINK_MAP_ENTRY (so) + struct so_list *so; +{ + return 0; +} + +#else /* SVR4_SHARED_LIBS */ + +static CORE_ADDR +LM_ADDR (so) + struct so_list *so; +{ +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + return extract_address (&so->lm32.l_addr, sizeof (so->lm32.l_addr)); + else +#endif + return extract_address (&so->lm.l_addr, sizeof (so->lm.l_addr)); +} + +static CORE_ADDR +LM_NEXT (so) + struct so_list *so; +{ +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + return extract_address (&so->lm32.l_next, sizeof (so->lm32.l_next)); + else +#endif + return extract_address (&so->lm.l_next, sizeof (so->lm.l_next)); +} + +static CORE_ADDR +LM_NAME (so) + struct so_list *so; +{ +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + return extract_address (&so->lm32.l_name, sizeof (so->lm32.l_name)); + else +#endif + return extract_address (&so->lm.l_name, sizeof (so->lm.l_name)); +} + +static int +IGNORE_FIRST_LINK_MAP_ENTRY (so) + struct so_list *so; +{ +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + return (solib_extract_address (&(so) -> lm32.l_prev) == 0); + else +#endif + return (solib_extract_address (&(so) -> lm.l_prev) == 0); +} + +#endif /* !SVR4_SHARED_LIBS */ + + static CORE_ADDR debug_base; /* Base of dynamic linker structures */ static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */ @@ -925,12 +1036,23 @@ first_link_map_member (void) } #else /* SVR4_SHARED_LIBS */ - - read_memory (debug_base, (char *) &debug_copy, sizeof (struct r_debug)); +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + { + read_memory (debug_base, (char *) &debug32_copy, + sizeof (struct r_debug32)); + lm = SOLIB_EXTRACT_ADDRESS (debug32_copy.r_map); + } + else +#endif + { + read_memory (debug_base, (char *) &debug_copy, + sizeof (struct r_debug)); + lm = SOLIB_EXTRACT_ADDRESS (debug_copy.r_map); + } /* FIXME: Perhaps we should validate the info somehow, perhaps by checking r_version for a known version number, or r_state for RT_CONSISTENT. */ - lm = SOLIB_EXTRACT_ADDRESS (debug_copy.r_map); #endif /* !SVR4_SHARED_LIBS */ @@ -962,7 +1084,6 @@ open_symbol_file_object (from_ttyp) int *from_ttyp; /* sneak past catch_errors */ { CORE_ADDR lm; - struct link_map lmcopy; char *filename; int errcode; @@ -977,15 +1098,35 @@ open_symbol_file_object (from_ttyp) if ((lm = first_link_map_member ()) == 0) return 0; /* failed somehow... */ - /* Read from target memory to GDB. */ - read_memory (lm, (void *) &lmcopy, sizeof (lmcopy)); +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + { + struct link_map32 lmcopy; + /* Read from target memory to GDB. */ + read_memory (lm, (void *) &lmcopy, sizeof (lmcopy)); - if (lmcopy.l_name == 0) - return 0; /* no filename. */ + if (lmcopy.l_name == 0) + return 0; /* no filename. */ + + /* Now fetch the filename from target memory. */ + target_read_string (SOLIB_EXTRACT_ADDRESS (lmcopy.l_name), + &filename, MAX_PATH_SIZE - 1, &errcode); + } + else +#endif /* HAVE_STRUCT_LINK_MAP32 */ + { + struct link_map lmcopy; + /* Read from target memory to GDB. */ + read_memory (lm, (void *) &lmcopy, sizeof (lmcopy)); + + if (lmcopy.l_name == 0) + return 0; /* no filename. */ + + /* Now fetch the filename from target memory. */ + target_read_string (SOLIB_EXTRACT_ADDRESS (lmcopy.l_name), &filename, + MAX_PATH_SIZE - 1, &errcode); + } - /* Now fetch the filename from target memory. */ - target_read_string (SOLIB_EXTRACT_ADDRESS (lmcopy.l_name), &filename, - MAX_PATH_SIZE - 1, &errcode); if (errcode) { warning ("failed to read exec filename from attached file: %s", @@ -1114,7 +1255,13 @@ current_sos (void) memset (new, 0, sizeof (*new)); new->lmaddr = lm; - read_memory (lm, (char *) &(new->lm), sizeof (struct link_map)); + +#if defined (HAVE_STRUCT_LINK_MAP32) + if (bfd_elf_get_arch_size (exec_bfd) == 32) + read_memory (lm, (char *) &(new->lm32), sizeof (struct link_map32)); + else +#endif + read_memory (lm, (char *) &(new->lm), sizeof (struct link_map)); lm = LM_NEXT (new); diff --git a/gdb/valops.c b/gdb/valops.c index 19482f1bff..8a7f03693b 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -286,8 +286,8 @@ value_cast (struct type *type, register value_ptr arg2) (LONGEST) (longest ? 1 : 0) : longest); } else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || - code2 == TYPE_CODE_ENUM || - code2 == TYPE_CODE_RANGE)) + code2 == TYPE_CODE_ENUM || + code2 == TYPE_CODE_RANGE)) { int ptr_bit = HOST_CHAR_BIT * TYPE_LENGTH (type); LONGEST longest = value_as_long (arg2); -- 2.34.1