From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 2e6yNV6Vw2r7TjwAWB0awg (envelope-from ) for ; Mon, 05 Oct 2026 08:17:34 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=awk63Uc+; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id D6B031E050; Mon, 05 Oct 2026 08:17:34 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 33BDE1E04E for ; Mon, 05 Oct 2026 08:17:33 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E8A3F4BA2E29 for ; Mon, 5 Oct 2026 12:17:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E8A3F4BA2E29 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=awk63Uc+ Received: from mail-dy1-x1334.google.com (mail-dy1-x1334.google.com [IPv6:2607:f8b0:4864:20::1334]) by sourceware.org (Postfix) with ESMTPS id A4CBF4BA2E11 for ; Mon, 5 Oct 2026 12:16:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A4CBF4BA2E11 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A4CBF4BA2E11 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1334 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791202617; cv=none; b=Opm5aGBFZyS3jIylLKJ82eTia7A1QavEx2jtIAG5E+QMBzv9ATprt1XyiRwWgasC9XNIhosaDs17yA1xwT0XjunbJiloieB5FuuEMTwhRe+cCNDvhd5a0LdpTbg1yaBrvXEmDX/2l7QHjKa2kxWKxy64zVlNzompc/XC5tajAR8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791202617; c=relaxed/simple; bh=AL2LtC1zBPkxYz/rztEw+VI/8FLzpK4Go7iYjIFvol8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=dakrBgidrDKNWD5Iwcs+N03phH2FOatrSJnhh6ragJso6I9SA+QiA67aa+9YbTfIi3PuVki05dkrPmuqyox9ueLPM8d8YifhblpVulDlip9s5b7ABFNy8hBrMgWlgX0turqLujniHYOHXDqIQjOZH7+xJ/DBFHNoVloIYByjDGg= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=awk63Uc+ DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A4CBF4BA2E11 Received: by mail-dy1-x1334.google.com with SMTP id 5a478bee46e88-35120d43ecaso2207629eec.1 for ; Mon, 05 Oct 2026 05:16:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791202616; x=1791807416; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=oSgSPH5ixEDsAp07ST0qThiG817cydXz+fwXooepepw=; b=awk63Uc+D/SmoTL24b9cG0Jqvpz/DaqjxX5D1qnAzQtLj5qtUG5JgQVov3LZCx6Lm8 209oH+YuvulA0UIbr8+4JkGfESWv0kjlqsjdlIY3bSfLIo8rGx7aOvuBhTkShrFumXnR Cjz8Dm1WKQpM/zlzxhibP+2ehJXE4KWFYu5vJS3J9dZTNGjP8/viV02mgOZE6a1V6+0Q 8jOhjd23afNLGj3dXBry7cUkOQEA+YI9oK497aQnv7Y1QlndqnP6+WfhaSCSCIIpE1hs Zy/NzSrLdg3I/RE5p4hzCq7qvYHzQ6eE7YJOgQNxxO7NjsRYd70tj+YI70MW37lmG6/f eoFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791202616; x=1791807416; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=oSgSPH5ixEDsAp07ST0qThiG817cydXz+fwXooepepw=; b=GehrVhn2kN8pyFle+d0/5Cjc5KZ10sTG6IQyyBHdfsWlMq20SUAX58qOrHgJqwnjqX qlnFjgYmm2AFAliX65aV+qFrEArEPO0gZG17nmiPRhNvczlXN6fpm5Xh73sc7rDbLfAV gUQ2W1ie2Tuq2F7cH+nEHubG6GqDDCwqUT3Yyw8NGHuqq3cqhSEUC4urrPvhrL4k3qHk VzjDD3y4qmex6+4BRT3UOZDy41Q6/fAMnUYjOQBpfx4e7/jPBJjlA+2ZeUv80iQP7hUY J+OII6+7i7PTuvfKEpcWwPXokINGQA1rPpN+jkCJbdX6XrS4UJCjrfLT9IUiguwqGf7S eL3g== X-Gm-Message-State: AFuF++lkMEH4vUtM+Mhp1OcI2kWynVQKgFMVSUnrMm2jH9gY7z+fjUpN AQVwJ7xZXH/Q1JeZPuW0Zm0mPjdtqwdbhkOZTdZ5xqQeGkUuKgdB9SYk X-Gm-Gg: AYBFou2R+g9TaBRgO1HBSfxcG+m74W2qNtCdWXZM4bqH+D0HcCEiBXV8izEc88Dwjzp 1+FHoAdXIBqco1DHpttjD9S6OcCi71dCFyXqxu/7X8WqplLnXxWBN+PmGpBPbt38uodO7JH2yig aad8usmDOf7AUYK1VVkFWelUkUDXQKraGbxdkPV9+nVv144Ef5PENFBTinbLWggXmDputTo2dvM n3kqVKJa9VBZTTssc67SWNox7QQbun20exOdRmUjfRzpDfudgYu5B9J3Ju7aOnKflgP5w+CHLQt b4nQoxKc/rTrAnsyNqwtqePjoxklbVoNxeDykY7+kCQdPVWssPzsG22EQoBZKM4v0xqFuK4O7rD gq7BxqvoYcqevBkNUw/MlK7Ra0a7KmkjZ4IRKBGWP+NL+OQUCupel/cHRj7uB0UA4SqYRnBLhLF +gRedQ+dgtmaEitKWa1+IlDKLe8VeEmfdlU6MSzsTMXEixr8n4LFVs92aWviMPA6rFd795nvNhT I5qTFr7UJS24noa3qUA636N92A= X-Received: by 2002:a05:693c:639c:10b0:351:1bdb:e3b7 with SMTP id 5a478bee46e88-3511bdbe7ffmr6858028eec.15.1791202615293; Mon, 05 Oct 2026 05:16:55 -0700 (PDT) Received: from localhost.localdomain ([122.171.21.153]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-35126f01924sm14038873eec.0.2026.10.05.05.16.52 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 05 Oct 2026 05:16:54 -0700 (PDT) From: Aditya Vidyadhar Kamath To: ulrich.weigand@de.ibm.com, simon.marchi@polymtl.ca, tom@tromey.com Cc: gdb-patches@sourceware.org, Aditya.Kamath1@ibm.com, sangamesh.swamy@in.ibm.com, Aditya Vidyadhar Kamath Subject: [PATCH v4 2/4] Remove stale legacy code from rs6000-aix-nat.c file. Date: Mon, 5 Oct 2026 17:46:10 +0530 Message-ID: <20261005121609.31787-2-akamath996@gmail.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org From: Aditya Vidyadhar Kamath GDB on AIX is built in 64 bit mode only. As per https://www.ibm.com/docs/en/aix/7.2.0?topic=p-ptrace-ptracex-ptrace64-subroutine though ptrace64 will also support 32-bit debugees if debugee is a 32 bit process, the options that refer to GPRs or SPRs fail with errno = EIO. This is something I have left in the comments of the code as well, so we do not miss it while testing. When I built GDB as a 64 bit AIX application [Using ptrace () for 32 bit inferior debugee] to just test, linking fails with: CXXLD gdb ld: 0711-317 ERROR: Undefined symbol: .ptrace ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information. collect2: error: ld returned 8 exit status gmake[2]: *** [Makefile:2367: gdb] Error 1 This clearly shows from AIX 7.2, the standard ptrace system call symbol is not exported in 64-bit mode; 64 bit mode must use ptrace64 exclusively which is what this patch does. As document mentioned, ptrace: 32- or 64-bit GDB, 32-bit inferior ptracex: 32-bit GDB, 64-bit inferior ptrace64: 64-bit GDB, 64-bit inferior This is right, Legacy rs6000_ptrace32 and rs6000_ptrace64 wrappers conditionally called ptrace/ptracex/ptrace64 and relied on ARCH3264 macro. This macro is now not needed. We will only use ptrace64 going forward. This patch modernises rs6000-aix-nat.c for AIX 7.2+/7.3+ Here are my thoughts during implementation. 1: Remove rs6000_ptrace32 () and rs6000_ptrace64 () completey. We will only use ptrace64 for all operations. No ptracex/ptrace any more since GDB will not be built in 32 bit mode. 2: Wrote get_thread_id () helper to obtain kernel thread ID via getthrds64 () 3: For a 32 bit debugee where process-level PT_READ_GPR, PT_WRITE_GPR and PT_READ_FPR/PT_WRITE_FPR fail with EIO when called from 64 bit GDB via ptrace64 () let us use thread-level PTT_READ_GPRS/PTT_WRITE_GPRS and PTT_READ_SPRS/PTT_WRITE_SPRS. Likewise, PTT_READ_FPRS/PTT_WRITE_FPRS. I also ran tests for for both 64 bit and 32 bit mode. First result is 64 bit mode. Second summary is 32 bit. Ran the command in gdb/testsuite directory. Command used: gmake check RUNTESTFLAGS='--directory=gdb.base CC_FOR_TARGET="/opt/freeware/bin/gcc" CXX_FOR_TARGET="/opt/freeware/bin/g++" CXXFLAGS_FOR_TARGET="-O0 -w -g -gdwarf -maix64" CFLAGS_FOR_TARGET="-O0 -w -g -gdwarf -maix64"' Before this patch: === gdb Summary === # of unexpected core files 1 # of expected passes 41792 # of unexpected failures 2346 # of unexpected successes 1 # of expected failures 17 # of known failures 30 # of unresolved testcases 30 # of untested testcases 104 # of unsupported tests 179 # of paths in test names 7 # of duplicate test names 2 -------------------------------------------------- === gdb Summary === # of unexpected core files 1 # of expected passes 41687 # of unexpected failures 2302 # of unexpected successes 1 # of expected failures 15 # of known failures 30 # of unresolved testcases 11 # of untested testcases 107 # of unsupported tests 179 # of paths in test names 7 # of duplicate test names 2 After this patch: === gdb Summary === # of unexpected core files 1 # of expected passes 41617 # of unexpected failures 2297 # of unexpected successes 1 # of expected failures 15 # of known failures 30 # of unresolved testcases 10 # of untested testcases 108 # of unsupported tests 179 # of paths in test names 7 # of duplicate test names 2 ------------------------------------ === gdb Summary === # of unexpected core files 1 # of expected passes 41796 # of unexpected failures 2346 # of unexpected successes 1 # of expected failures 17 # of known failures 30 # of unresolved testcases 31 # of untested testcases 105 # of unsupported tests 179 # of paths in test names 7 # of duplicate test names 2 -------------------------------------------------- --- gdb/rs6000-aix-nat.c | 306 +++++++++++++++++++++---------------------- 1 file changed, 148 insertions(+), 158 deletions(-) diff --git a/gdb/rs6000-aix-nat.c b/gdb/rs6000-aix-nat.c index 276df378824..6113bf988bc 100644 --- a/gdb/rs6000-aix-nat.c +++ b/gdb/rs6000-aix-nat.c @@ -60,24 +60,9 @@ /* Header files for alti-vec reg. */ #include -/* On AIX4.3+, sys/ldr.h provides different versions of struct ld_info for - debugging 32-bit and 64-bit processes. Define a typedef and macros for - accessing fields in the appropriate structures. */ - -/* In 32-bit compilation mode (which is the only mode from which ptrace() - works on 4.3), __ld_info32 is #defined as equivalent to ld_info. */ - -#if defined (__ld_info32) || defined (__ld_info64) -# define ARCH3264 -#endif - /* Return whether the current architecture is 64-bit. */ -#ifndef ARCH3264 -# define ARCH64() 0 -#else -# define ARCH64() (register_size (current_inferior ()->arch (), 0) == 8) -#endif +#define ARCH64() (register_size (current_inferior ()->arch (), 0) == 8) class rs6000_nat_target final : public inf_ptrace_target { @@ -246,42 +231,20 @@ regmap (struct gdbarch *gdbarch, int regno, int *isfloat) return -1; } -/* Call ptrace(REQ, ID, ADDR, DATA, BUF). */ +/* Return the thread ID of the first kernel thread in PID, or 0 on + failure. Used to call PTT_* requests which require a tid rather + than a pid. */ -static int -rs6000_ptrace32 (int req, int id, int *addr, int data, int *buf) +static tid64_t +get_thread_id (pid_t pid) { -#ifdef HAVE_PTRACE64 - int ret = ptrace64 (req, id, (uintptr_t) addr, data, buf); -#else - int ret = ptrace (req, id, (int *)addr, data, buf); -#endif -#if 0 - printf ("rs6000_ptrace32 (%d, %d, 0x%x, %08x, 0x%x) = 0x%x\n", - req, id, (unsigned int)addr, data, (unsigned int)buf, ret); -#endif - return ret; -} - -/* Call ptracex(REQ, ID, ADDR, DATA, BUF). */ + struct thrdentry64 thrdentry; + tid64_t thrd_i = 0; -static int -rs6000_ptrace64 (int req, int id, long long addr, int data, void *buf) -{ -#ifdef ARCH3264 -# ifdef HAVE_PTRACE64 - int ret = ptrace64 (req, id, addr, data, (PTRACE_TYPE_ARG5) buf); -# else - int ret = ptracex (req, id, addr, data, (PTRACE_TYPE_ARG5) buf); -# endif -#else - int ret = 0; -#endif -#if 0 - printf ("rs6000_ptrace64 (%d, %d, %s, %08x, 0x%x) = 0x%x\n", - req, id, hex_string (addr), data, (unsigned int)buf, ret); -#endif - return ret; + if (getthrds64 (pid, &thrdentry, sizeof (struct thrdentry64), + &thrd_i, 1) == 1) + return thrdentry.ti_tid; + return 0; } /* Store the vsx registers. */ @@ -292,32 +255,21 @@ store_vsx_register_aix (struct regcache *regcache, int regno) int ret; struct gdbarch *gdbarch = regcache->arch (); ppc_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - struct thrdentry64 thrdentry; __vsx_context_t vsx; pid_t pid = inferior_ptid.pid (); - tid64_t thrd_i = 0; - - if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64), - &thrd_i, 1) == 1) - thrd_i = thrdentry.ti_tid; + tid64_t thrd_i = get_thread_id (pid); memset(&vsx, 0, sizeof(__vsx_context_t)); if (__power_vsx() && thrd_i > 0) { - if (ARCH64 ()) - ret = rs6000_ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0); - else - ret = rs6000_ptrace32 (PTT_READ_VSX, thrd_i, (int *)&vsx, 0, 0); + ret = ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0); if (ret < 0) return; regcache->raw_collect (regno, &(vsx.__vsr_dw1[0])+ regno - tdep->ppc_vsr0_upper_regnum); - if (ARCH64 ()) - ret = rs6000_ptrace64 (PTT_WRITE_VSX, thrd_i, (long long) &vsx, 0, 0); - else - ret = rs6000_ptrace32 (PTT_WRITE_VSX, thrd_i, (int *) &vsx, 0, 0); + ret = ptrace64 (PTT_WRITE_VSX, thrd_i, (long long) &vsx, 0, 0); if (ret < 0) perror_with_name (_("Unable to write VSX registers after reading it")); @@ -332,32 +284,21 @@ store_altivec_register_aix (struct regcache *regcache, int regno) int ret; struct gdbarch *gdbarch = regcache->arch (); ppc_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - struct thrdentry64 thrdentry; __vmx_context_t vmx; pid_t pid = inferior_ptid.pid (); - tid64_t thrd_i = 0; - - if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64), - &thrd_i, 1) == 1) - thrd_i = thrdentry.ti_tid; + tid64_t thrd_i = get_thread_id (pid); memset(&vmx, 0, sizeof(__vmx_context_t)); if (__power_vmx() && thrd_i > 0) { - if (ARCH64 ()) - ret = rs6000_ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0); - else - ret = rs6000_ptrace32 (PTT_READ_VEC, thrd_i, (int *) &vmx, 0, 0); + ret = ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0); if (ret < 0) return; regcache->raw_collect (regno, &(vmx.__vr[0]) + regno - tdep->ppc_vr0_regnum); - if (ARCH64 ()) - ret = rs6000_ptrace64 (PTT_WRITE_VEC, thrd_i, (long long) &vmx, 0, 0); - else - ret = rs6000_ptrace32 (PTT_WRITE_VEC, thrd_i, (int *) &vmx, 0, 0); + ret = ptrace64 (PTT_WRITE_VEC, thrd_i, (long long) &vmx, 0, 0); if (ret < 0) perror_with_name (_("Unable to store AltiVec register after reading it")); } @@ -385,22 +326,14 @@ supply_vrregset_aix (struct regcache *regcache, __vmx_context_t *vmx) static void fetch_altivec_registers_aix (struct regcache *regcache) { - struct thrdentry64 thrdentry; __vmx_context_t vmx; pid_t pid = current_inferior ()->pid; - tid64_t thrd_i = 0; - - if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64), - &thrd_i, 1) == 1) - thrd_i = thrdentry.ti_tid; + tid64_t thrd_i = get_thread_id (pid); memset(&vmx, 0, sizeof(__vmx_context_t)); if (__power_vmx() && thrd_i > 0) { - if (ARCH64 ()) - rs6000_ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0); - else - rs6000_ptrace32 (PTT_READ_VEC, thrd_i, (int *) &vmx, 0, 0); + ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0); supply_vrregset_aix (regcache, &vmx); } } @@ -423,22 +356,14 @@ supply_vsxregset_aix (struct regcache *regcache, __vsx_context_t *vsx) static void fetch_vsx_registers_aix (struct regcache *regcache) { - struct thrdentry64 thrdentry; __vsx_context_t vsx; pid_t pid = current_inferior ()->pid; - tid64_t thrd_i = 0; - - if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64), - &thrd_i, 1) == 1) - thrd_i = thrdentry.ti_tid; + tid64_t thrd_i = get_thread_id (pid); memset(&vsx, 0, sizeof(__vsx_context_t)); if (__power_vsx() && thrd_i > 0) { - if (ARCH64 ()) - rs6000_ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0); - else - rs6000_ptrace32 (PTT_READ_VSX, thrd_i, (int *) &vsx, 0, 0); + ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0); supply_vsxregset_aix (regcache, &vsx); } } @@ -451,10 +376,7 @@ void rs6000_nat_target::post_startup_inferior (ptid_t ptid) with the process ID which can fork () and the data parameter [fourth parameter] must be 1. */ - if (!ARCH64 ()) - rs6000_ptrace32 (PT_MULTI, ptid.pid(), 0, 1, 0); - else - rs6000_ptrace64 (PT_MULTI, ptid.pid(), 0, 1, 0); + ptrace64 (PT_MULTI, ptid.pid(), 0, 1, 0); } void @@ -477,10 +399,7 @@ rs6000_nat_target::follow_fork (inferior *child_inf, ptid_t child_ptid, if (detach_fork && !follow_child) { - if (ARCH64 ()) - rs6000_ptrace64 (PT_DETACH, child_ptid.pid (), 0, 0, 0); - else - rs6000_ptrace32 (PT_DETACH, child_ptid.pid (), 0, 0, 0); + ptrace64 (PT_DETACH, child_ptid.pid (), 0, 0, 0); } } @@ -528,7 +447,23 @@ fetch_register (struct regcache *regcache, int regno) /* Floating-point registers. */ if (isfloat) - rs6000_ptrace32 (PT_READ_FPR, pid, addr, nr, 0); + { + if (ARCH64 ()) + ptrace64 (PT_READ_FPR, pid, (long long) addr, nr, 0); + else + { + /* PT_READ_FPR via ptrace64 fails with EIO for a 32-bit inferior. + Use PTT_READ_FPRS (thread-level) instead, which works for both + 32-bit and 64-bit inferiors from a 64-bit debugger. */ + double fprs[ppc_num_fprs]; + tid64_t tid = get_thread_id (pid); + if (tid > 0) + { + ptrace64 (PTT_READ_FPRS, tid, (long long) fprs, 0, 0); + memcpy (addr, &fprs[nr - FPR0], 8); + } + } + } /* Bogus register number. */ else if (nr < 0) @@ -543,31 +478,59 @@ fetch_register (struct regcache *regcache, int regno) /* Fixed-point registers. */ else { - if (!ARCH64 ()) - *addr = rs6000_ptrace32 (PT_READ_GPR, pid, (int *) nr, 0, 0); - else + if (ARCH64 ()) { - /* PT_READ_GPR requires the buffer parameter to point to long long, - even if the register is really only 32 bits. */ + /* PT_READ_GPR via ptrace64 works for 64-bit inferiors. + The buffer parameter must point to a long long area. */ long long buf; - rs6000_ptrace64 (PT_READ_GPR, pid, nr, 0, &buf); + ptrace64 (PT_READ_GPR, pid, nr, 0, (PTRACE_TYPE_ARG5) &buf); if (register_size (gdbarch, regno) == 8) memcpy (addr, &buf, 8); else *addr = buf; } + else + { + /* PT_READ_GPR via ptrace64 fails with EIO for a 32-bit inferior. + Use PTT_READ_GPRS / PTT_READ_SPRS (thread-level) instead. */ + tid64_t tid = get_thread_id (pid); + if (tid > 0) + { + if (nr >= 0 && nr < ppc_num_gprs) + { + /* GPR: PTT_READ_GPRS writes all 32 GPRs as unsigned int[32]. + Index directly by register number. */ + unsigned int gprs[ppc_num_gprs]; + ptrace64 (PTT_READ_GPRS, tid, (long long) gprs, 0, 0); + *addr = gprs[nr]; + } + else + { + /* SPR: PTT_READ_SPRS writes a ptsprs struct. Map the + register number back to the appropriate field. */ + struct ptsprs sprs; + ptrace64 (PTT_READ_SPRS, tid, (long long) &sprs, 0, 0); + switch (nr) + { + case IAR: *addr = sprs.pt_iar; break; + case MSR: *addr = sprs.pt_msr; break; + case CR: *addr = sprs.pt_cr; break; + case LR: *addr = sprs.pt_lr; break; + case CTR: *addr = sprs.pt_ctr; break; + case XER: *addr = sprs.pt_xer; break; + case MQ: *addr = sprs.pt_mq; break; + case FPSCR: *addr = sprs.pt_fpscr; break; + default: return; + } + } + } + } } if (!errno) regcache->raw_supply (regno, (char *) addr); else - { -#if 0 - /* FIXME: this happens 3 times at the start of each 64-bit program. */ - perror (_("ptrace read")); -#endif - errno = 0; - } + errno = 0; } /* Store register REGNO back into the inferior. */ @@ -602,7 +565,24 @@ store_register (struct regcache *regcache, int regno) /* Floating-point registers. */ if (isfloat) - rs6000_ptrace32 (PT_WRITE_FPR, pid, addr, nr, 0); + { + if (ARCH64 ()) + ptrace64 (PT_WRITE_FPR, pid, (long long) addr, nr, 0); + else + { + /* PT_WRITE_FPR via ptrace64 fails with EIO for a 32-bit inferior. + Use PTT_WRITE_FPRS (thread-level) instead: read all FPRs, update + the one register, then write them all back. */ + double fprs[ppc_num_fprs]; + tid64_t tid = get_thread_id (pid); + if (tid > 0) + { + ptrace64 (PTT_READ_FPRS, tid, (long long) fprs, 0, 0); + memcpy (&fprs[nr - FPR0], addr, 8); + ptrace64 (PTT_WRITE_FPRS, tid, (long long) fprs, 0, 0); + } + } + } /* Bogus register number. */ else if (nr < 0) @@ -616,21 +596,52 @@ store_register (struct regcache *regcache, int regno) /* Fixed-point registers. */ else { - /* The PT_WRITE_GPR operation is rather odd. For 32-bit inferiors, - the register's value is passed by value, but for 64-bit inferiors, - the address of a buffer containing the value is passed. */ - if (!ARCH64 ()) - rs6000_ptrace32 (PT_WRITE_GPR, pid, (int *) nr, *addr, 0); - else + if (ARCH64 ()) { - /* PT_WRITE_GPR requires the buffer parameter to point to an 8-byte - area, even if the register is really only 32 bits. */ + /* PT_WRITE_GPR via ptrace64 works for 64-bit inferiors. + The buffer parameter must point to an 8-byte area. */ long long buf; if (register_size (gdbarch, regno) == 8) memcpy (&buf, addr, 8); else buf = *addr; - rs6000_ptrace64 (PT_WRITE_GPR, pid, nr, 0, &buf); + ptrace64 (PT_WRITE_GPR, pid, nr, 0, (PTRACE_TYPE_ARG5) &buf); + } + else + { + /* PT_WRITE_GPR via ptrace64 fails with EIO for a 32-bit inferior. + Use PTT_WRITE_GPRS / PTT_WRITE_SPRS (thread-level) instead. */ + tid64_t tid = get_thread_id (pid); + if (tid > 0) + { + if (nr >= 0 && nr < ppc_num_gprs) + { + /* GPR: read all 32, update one, write all back. */ + unsigned int gprs[ppc_num_gprs]; + ptrace64 (PTT_READ_GPRS, tid, (long long) gprs, 0, 0); + gprs[nr] = *addr; + ptrace64 (PTT_WRITE_GPRS, tid, (long long) gprs, 0, 0); + } + else + { + /* SPR: read ptsprs, update one field, write back. */ + struct ptsprs sprs; + ptrace64 (PTT_READ_SPRS, tid, (long long) &sprs, 0, 0); + switch (nr) + { + case IAR: sprs.pt_iar = *addr; break; + case MSR: sprs.pt_msr = *addr; break; + case CR: sprs.pt_cr = *addr; break; + case LR: sprs.pt_lr = *addr; break; + case CTR: sprs.pt_ctr = *addr; break; + case XER: sprs.pt_xer = *addr; break; + case MQ: sprs.pt_mq = *addr; break; + case FPSCR: sprs.pt_fpscr = *addr; break; + default: return; + } + ptrace64 (PTT_WRITE_SPRS, tid, (long long) &sprs, 0, 0); + } + } } } @@ -760,7 +771,6 @@ rs6000_nat_target::xfer_partial (enum target_object object, ULONGEST *xfered_len) { pid_t pid = inferior_ptid.pid (); - int arch64 = ARCH64 (); switch (object) { @@ -801,14 +811,8 @@ rs6000_nat_target::xfer_partial (enum target_object object, < rounded_offset + sizeof (PTRACE_TYPE_RET))) { /* Need part of initial word -- fetch it. */ - if (arch64) - buffer.word = rs6000_ptrace64 (PT_READ_I, pid, - rounded_offset, 0, NULL); - else - buffer.word = rs6000_ptrace32 (PT_READ_I, pid, - (int *) (uintptr_t) - rounded_offset, - 0, NULL); + buffer.word = ptrace64 (PT_READ_I, pid, + rounded_offset, 0, NULL); } /* Copy data to be written over corresponding part of @@ -817,13 +821,8 @@ rs6000_nat_target::xfer_partial (enum target_object object, writebuf, partial_len); errno = 0; - if (arch64) - rs6000_ptrace64 (PT_WRITE_D, pid, - rounded_offset, buffer.word, NULL); - else - rs6000_ptrace32 (PT_WRITE_D, pid, - (int *) (uintptr_t) rounded_offset, - buffer.word, NULL); + ptrace64 (PT_WRITE_D, pid, + rounded_offset, buffer.word, NULL); if (errno) return TARGET_XFER_EOF; } @@ -831,13 +830,8 @@ rs6000_nat_target::xfer_partial (enum target_object object, if (readbuf) { errno = 0; - if (arch64) - buffer.word = rs6000_ptrace64 (PT_READ_I, pid, - rounded_offset, 0, NULL); - else - buffer.word = rs6000_ptrace32 (PT_READ_I, pid, - (int *)(uintptr_t)rounded_offset, - 0, NULL); + buffer.word = ptrace64 (PT_READ_I, pid, + rounded_offset, 0, NULL); if (errno) return TARGET_XFER_EOF; @@ -1014,12 +1008,8 @@ rs6000_ptrace_ldinfo (ptid_t ptid) while (1) { - if (ARCH64 ()) - rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi.data (), - ldi.size (), NULL); - else - rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi.data (), - ldi.size (), NULL); + rc = ptrace64 (PT_LDINFO, pid, (unsigned long) ldi.data (), + ldi.size (), NULL); if (rc != -1) break; /* Success, we got the entire ld_info data. */ -- 2.51.2