From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26781 invoked by alias); 4 Dec 2003 20:10:08 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 26730 invoked from network); 4 Dec 2003 20:10:07 -0000 Received: from unknown (HELO faui10.informatik.uni-erlangen.de) (131.188.31.10) by sources.redhat.com with SMTP; 4 Dec 2003 20:10:07 -0000 Received: from faui1d.informatik.uni-erlangen.de (faui1d [131.188.31.34]) by faui10.informatik.uni-erlangen.de (8.9.3p3/8.1.9-FAU) with ESMTP id VAA22254; Thu, 4 Dec 2003 21:10:06 +0100 (CET) From: Ulrich Weigand Received: (from weigand@localhost) by faui1d.informatik.uni-erlangen.de (8.9.3p3/8.1.6-FAU) id VAA07741; Thu, 4 Dec 2003 21:10:05 +0100 (CET) Message-Id: <200312042010.VAA07741@faui1d.informatik.uni-erlangen.de> Subject: [PATCH] S/390 bi-arch debugging support To: gdb-patches@sources.redhat.com Date: Thu, 04 Dec 2003 20:10:00 -0000 Cc: uweigand@de.ibm.com MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2003-12/txt/msg00131.txt.bz2 Hello, this patch adds support for debugging 32-bit applications running under a 64-bit kernel from within a 64-bit gdb. This involves only a minor change in s390-nat.c to convert register values between 64-bit and 32-bit formats, and installing a solib_svr4_fetch_link_map_offsets handler. Tested on s390-ibm-linux and s390x-ibm-linux with no new regressions. When running the test suite in 32-bit mode (i.e. make check RUNTESTFLAGS="CC_FOR_TARGET='gcc -m31' ..."), several test cases are still failing: - asm-source.exp because it uses the wrong assembler file (I didn't bother to fix that) - dump.exp because it gets confused by a 32/64-bit size mismatch: it computes a difference between two target addresses (which happens to be negative), prints this using "/x" so that it gets converted to a *32-bit* unsigned hex value on 32-bit targets. This is then used as argument to the 'restore' command, which interprets its argument as *64-bit* unsigned long value on 64-bit hosts, and performs a 64-bit addition to arrive at the (now incorrect) destination address. I've simply changed the test case to use decimal representation for the offset, which includes the sign -- then everything gets computed correctly. If you think the test case should work fine as is and gdb needs to be fixed, just ignore that part of the patch. - gcore.exp because generate-core writes 64-bit style NOTEs into a 32-bit format core dump file. This is because gdb calls into bfd's elfcore_write_prpsinfo, which always writes a NOTE in the current host's format without checking the target at all. I guess this needs to be fixed in bfd. - All multi-threaded test cases fail. This is because they use the proc-service API implemented in linuxthreads_db, and this appears to be fundamentally unsuited to handle 32-bit processes on a 64-bit host ... I have no idea what to do here. Bye, Ulrich ChangeLog: * s390-nat.c (supply_gregset, fill_gregset): Handle debugging of 32-bit exectuables running under a 64-bit kernel. * s390-tdep.c: Include "solib-svr4.h". (s390_svr4_fetch_link_map_offset): New function. (s390x_svr_fetch_link_map_offset): Likewise. (s390_gdbarch_init): Call set_solib_svr4_fetch_link_map_offsets. * Makefile.in (s390-tdep.o): Update dependencies. testsuite/ChangeLog: * gdb.base/dump.exp: Handle negative offsets in decimal, not hex. diff -c -p -r gdb-head/gdb/Makefile.in gdb-head-new/gdb/Makefile.in *** gdb-head/gdb/Makefile.in Wed Dec 3 23:50:44 2003 --- gdb-head-new/gdb/Makefile.in Thu Dec 4 03:14:20 2003 *************** s390-tdep.o: s390-tdep.c $(defs_h) $(arc *** 2254,2260 **** $(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \ $(objfiles_h) $(tm_h) $(__bfd_bfd_h) $(floatformat_h) $(regcache_h) \ $(trad_frame_h) $(frame_base_h) $(frame_unwind_h) $(dwarf2_frame_h) \ ! $(reggroups_h) $(regset_h) $(value_h) $(gdb_assert_h) $(dis_asm_h) scm-exp.o: scm-exp.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \ $(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \ $(scm_tags_h) --- 2254,2261 ---- $(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \ $(objfiles_h) $(tm_h) $(__bfd_bfd_h) $(floatformat_h) $(regcache_h) \ $(trad_frame_h) $(frame_base_h) $(frame_unwind_h) $(dwarf2_frame_h) \ ! $(reggroups_h) $(regset_h) $(value_h) $(gdb_assert_h) $(dis_asm_h) \ ! $(solib_svr4_h) scm-exp.o: scm-exp.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \ $(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \ $(scm_tags_h) diff -c -p -r gdb-head/gdb/s390-nat.c gdb-head-new/gdb/s390-nat.c *** gdb-head/gdb/s390-nat.c Thu Dec 4 03:09:05 2003 --- gdb-head-new/gdb/s390-nat.c Thu Dec 4 03:08:58 2003 *************** supply_gregset (gregset_t *regp) *** 112,118 **** int i; for (i = 0; i < s390_gregset_regmap_len; i++) if (s390_gregset_regmap[i] != -1) ! supply_register (i, (char *)regp + s390_gregset_regmap[i]); } /* Fill register REGNO (if it is a general-purpose register) in --- 112,128 ---- int i; for (i = 0; i < s390_gregset_regmap_len; i++) if (s390_gregset_regmap[i] != -1) ! { ! char *ptr = (char *)regp + s390_gregset_regmap[i]; ! #ifdef __s390x__ ! /* When debugging a 32-bit executable running under a 64-bit kernel, ! we have to fix up the 64-bit registers we get from the kernel ! to make them look like 32-bit registers. */ ! if (TARGET_PTR_BIT == 32 && i < 18) ! ptr += (i == 0) ? 0 : 4; ! #endif ! supply_register (i, ptr); ! } } /* Fill register REGNO (if it is a general-purpose register) in *************** fill_gregset (gregset_t *regp, int regno *** 125,131 **** for (i = 0; i < s390_gregset_regmap_len; i++) if (s390_gregset_regmap[i] != -1) if (regno == -1 || regno == i) ! regcache_collect (i, (char *)regp + s390_gregset_regmap[i]); } /* Fill GDB's register array with the floating-point register values --- 135,151 ---- for (i = 0; i < s390_gregset_regmap_len; i++) if (s390_gregset_regmap[i] != -1) if (regno == -1 || regno == i) ! { ! char *ptr = (char *)regp + s390_gregset_regmap[i]; ! #ifdef __s390x__ ! /* When debugging a 32-bit executable running under a 64-bit kernel, ! we have to fix up the 32-bit registers we get from the debugger ! to make them look like 64-bit registers. */ ! if (TARGET_PTR_BIT == 32 && i < 18) ! ptr += (i == 0) ? 0 : 4; ! #endif ! regcache_collect (i, ptr); ! } } /* Fill GDB's register array with the floating-point register values diff -c -p -r gdb-head/gdb/s390-tdep.c gdb-head-new/gdb/s390-tdep.c *** gdb-head/gdb/s390-tdep.c Thu Dec 4 03:09:05 2003 --- gdb-head-new/gdb/s390-tdep.c Thu Dec 4 00:08:03 2003 *************** *** 45,50 **** --- 45,51 ---- #include "value.h" #include "gdb_assert.h" #include "dis-asm.h" + #include "solib-svr4.h" /* For struct link_map_offsets. */ *************** s390_address_class_name_to_type_flags (s *** 2957,2962 **** --- 2958,3032 ---- } + /* Link map offsets. */ + + static struct link_map_offsets * + s390_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; + + 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; + } + + static struct link_map_offsets * + s390x_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 = 16; /* All we need. */ + + lmo.r_map_offset = 8; + lmo.r_map_size = 8; + + lmo.link_map_size = 40; /* All we need. */ + + lmo.l_addr_offset = 0; + lmo.l_addr_size = 8; + + lmo.l_name_offset = 8; + lmo.l_name_size = 8; + + lmo.l_next_offset = 24; + lmo.l_next_size = 8; + + lmo.l_prev_offset = 32; + lmo.l_prev_size = 8; + } + + return lmp; + } + + /* Set up gdbarch struct. */ static struct gdbarch * *************** s390_gdbarch_init (struct gdbarch_info i *** 3043,3048 **** --- 3113,3121 ---- set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove); set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, s390_pseudo_register_write); + set_solib_svr4_fetch_link_map_offsets (gdbarch, + s390_svr4_fetch_link_map_offsets); + break; case bfd_mach_s390_64: tdep->abi = ABI_LINUX_ZSERIES; *************** s390_gdbarch_init (struct gdbarch_info i *** 3057,3062 **** --- 3130,3137 ---- set_gdbarch_ptr_bit (gdbarch, 64); set_gdbarch_pseudo_register_read (gdbarch, s390x_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, s390x_pseudo_register_write); + set_solib_svr4_fetch_link_map_offsets (gdbarch, + s390x_svr4_fetch_link_map_offsets); set_gdbarch_address_class_type_flags (gdbarch, s390_address_class_type_flags); set_gdbarch_address_class_type_flags_to_name (gdbarch, diff -c -p -r gdb-head/gdb/testsuite/gdb.base/dump.exp gdb-head-new/gdb/testsuite/gdb.base/dump.exp *** gdb-head/gdb/testsuite/gdb.base/dump.exp Thu Dec 4 03:09:05 2003 --- gdb-head-new/gdb/testsuite/gdb.base/dump.exp Thu Dec 4 00:08:03 2003 *************** test_restore_saved_value "intstr2.bin bi *** 353,361 **** set array2_start [capture_value "/x &intarray2\[0\]"] set struct2_start [capture_value "/x &intstruct2"] set array2_offset \ ! [capture_value "/x (char *) &intarray2 - (char *) &intarray"] set struct2_offset \ ! [capture_value "/x (char *) &intstruct2 - (char *) &intstruct"] gdb_test "print zero_all ()" "" --- 353,361 ---- set array2_start [capture_value "/x &intarray2\[0\]"] set struct2_start [capture_value "/x &intstruct2"] set array2_offset \ ! [capture_value "(char *) &intarray2 - (char *) &intarray"] set struct2_offset \ ! [capture_value "(char *) &intstruct2 - (char *) &intstruct"] gdb_test "print zero_all ()" "" -- Dr. Ulrich Weigand weigand@informatik.uni-erlangen.de