From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 94189 invoked by alias); 20 Oct 2015 12:44:23 -0000 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 Received: (qmail 94158 invoked by uid 89); 20 Oct 2015 12:44:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,FSL_HELO_BARE_IP_2,RCVD_IN_DNSWL_LOW,RCVD_NUMERIC_HELO,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=no version=3.3.2 X-HELO: plane.gmane.org Received: from plane.gmane.org (HELO plane.gmane.org) (80.91.229.3) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 20 Oct 2015 12:44:19 +0000 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1ZoWGl-0007r0-AY for gdb-patches@sourceware.org; Tue, 20 Oct 2015 14:44:02 +0200 Received: from 209.226.137.108 ([209.226.137.108]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 20 Oct 2015 14:43:59 +0200 Received: from aristovski by 209.226.137.108 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 20 Oct 2015 14:43:59 +0200 To: gdb-patches@sourceware.org From: Aleksandar Ristovski Subject: Re: [PATCH 2/4] [nto] Fixes for nto procfs. Date: Tue, 20 Oct 2015 13:21:00 -0000 Message-ID: <56263704.6000007@qnx.com> References: <1444752074-878-1-git-send-email-aristovski@qnx.com> <1444752074-878-3-git-send-email-aristovski@qnx.com> <561FE53A.1050406@redhat.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------040709040403070109060802" Cc: Pedro Alves X-Enigmail-Draft-Status: N1110 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 In-Reply-To: <561FE53A.1050406@redhat.com> X-IsSubscribed: yes X-SW-Source: 2015-10/txt/msg00354.txt.bz2 This is a multi-part message in MIME format. --------------040709040403070109060802 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-length: 1663 On 15-10-15 01:41 PM, Pedro Alves wrote: > It would have been nicer to see this split into a fix/theme > per patch, and add something to the commit log about each > fix. E.g., the aux bits could easily be a separate patch. > > Anyway, this is pretty isolated to NTO bits. I'm trying to catch up and submit local changes for previous ports. While patches may not be minimalistic, I am trying to at least bring certain rounded-up improvement (e.g. having a debug session). But I will try to make more granulated patches. > > LGTM with the nits below addressed. > > On 10/13/2015 05:01 PM, Aleksandar Ristovski wrote: > >> } >> >> do_cleanups (inner_cleanup); >> @@ -599,9 +612,40 @@ procfs_files_info (struct target_ops *ignore) >> >> printf_unfiltered ("\tUsing the running image of %s %s via %s.\n", >> inf->attach_flag ? "attached" : "child", >> - target_pid_to_str (inferior_ptid), nto_procfs_path); >> + target_pid_to_str (inferior_ptid), >> + nodestr ? nodestr : "local node"); > > Write 'nodestr != NULL'. Done. Here and other places where pointer is used as a logical expression. ... >> + if (rd <= 0) >> + { >> + proc_path[0] = '\0'; >> + return NULL; >> + } >> + else >> + proc_path[rd] = '\0'; >> + >> + return proc_path; > > Either write: > > else > { > proc_path[rd] = '\0'; > return proc_path; > } > > Or drop the "else". Dropped 'else'. ... >> + >> + if (!tempbuf) >> + return TARGET_XFER_E_IO; > > if (tempbuf == NULL) > > Can NTO's alloca really return NULL? Yes. Attached fixed version of the patch. Thanks, Aleksandar Ristovski --------------040709040403070109060802 Content-Type: text/x-patch; name="0001-nto-Fixes-for-nto-procfs.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-nto-Fixes-for-nto-procfs.patch" Content-length: 13290 =46rom 62774c1deef7eb01108ac65636e2ccf974992d85 Mon Sep 17 00:00:00 2001 From: Aleksandar Ristovski Date: Mon, 5 Oct 2015 10:32:16 -0400 Subject: [PATCH] [nto] Fixes for nto procfs. gdb/ChangeLog: * nto-procfs.c (sys/auxv.h): Include. (nto_procfs_path): Rename to... (nodestr): ... this, and change type. (nto_node): Use new variable and logic accordingly. (procfs_open_1): Use new variable name. Use local buffer to construct procfs path. (procfs_pidlist): Use NODESTR to construct procfs path. (procfs_files_info): Use NODESTR to output meaningful text. (procfs_pid_to_exec_file): New target function. (do_attach): Construct procfs using NODESTR. (procfs_xfer_partial): Logic for reading TARGET_OBJECT_AUXV. (procfs_create_inferior): Compare pointer to NULL. (init_procfs_targets): Wire procfs_pid_to_exec_file. * nto-tdep.c (symfile.h): Include. (nto_read_auxv_from_initial_stack): New function. * nto-tdep.h (nto_read_auxv_from_initial_stack): New function declaration. --- gdb/nto-procfs.c | 128 ++++++++++++++++++++++++++++++++++++++++++++-------= ---- gdb/nto-tdep.c | 87 +++++++++++++++++++++++++++++++++++++ gdb/nto-tdep.h | 4 ++ 3 files changed, 194 insertions(+), 25 deletions(-) diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c index d659f79..176ceea 100644 --- a/gdb/nto-procfs.c +++ b/gdb/nto-procfs.c @@ -30,6 +30,8 @@ #include #include #include +#include + #include "gdbcore.h" #include "inferior.h" #include "target.h" @@ -73,7 +75,7 @@ static int procfs_stopped_by_watchpoint (struct target_op= s *ops); referenced elsewhere. 'nto_procfs_node' is a flag used to say whether we are local, or we should get the current node descriptor for the remote QNX node. */ -static char nto_procfs_path[PATH_MAX] =3D { "/proc" }; +static char *nodestr; static unsigned nto_procfs_node =3D ND_LOCAL_NODE; =20 /* Return the current QNX Node, or error out. This is a simple @@ -85,10 +87,11 @@ nto_node (void) { unsigned node; =20 - if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) =3D=3D 0) + if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) =3D=3D 0 + || nodestr =3D=3D NULL) return ND_LOCAL_NODE; =20 - node =3D netmgr_strtond (nto_procfs_path, 0); + node =3D netmgr_strtond (nodestr, 0); if (node =3D=3D -1) error (_("Lost the QNX node. Debug session probably over.")); =20 @@ -108,12 +111,12 @@ procfs_is_nto_target (bfd *abfd) static void procfs_open_1 (struct target_ops *ops, const char *arg, int from_tty) { - char *nodestr; char *endstr; char buffer[50]; int fd, total_size; procfs_sysinfo *sysinfo; struct cleanup *cleanups; + char nto_procfs_path[PATH_MAX]; =20 /* Offer to kill previous inferiors before opening this target. */ target_preopen (from_tty); @@ -123,8 +126,11 @@ procfs_open_1 (struct target_ops *ops, const char *arg= , int from_tty) /* Set the default node used for spawning to this one, and only override it if there is a valid arg. */ =20 + xfree (nodestr); + nodestr =3D NULL; + nto_procfs_node =3D ND_LOCAL_NODE; - nodestr =3D arg ? xstrdup (arg) : NULL; + nodestr =3D (arg !=3D NULL) ? xstrdup (arg) : NULL; =20 init_thread_list (); =20 @@ -149,10 +155,8 @@ procfs_open_1 (struct target_ops *ops, const char *arg= , int from_tty) *endstr =3D 0; } } - snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "", - "/proc"); - if (nodestr) - xfree (nodestr); + snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", + (nodestr !=3D NULL) ? nodestr : "", "/proc"); =20 fd =3D open (nto_procfs_path, O_RDONLY); if (fd =3D=3D -1) @@ -174,7 +178,7 @@ procfs_open_1 (struct target_ops *ops, const char *arg,= int from_tty) { total_size =3D sysinfo->total_size; sysinfo =3D alloca (total_size); - if (!sysinfo) + if (sysinfo =3D=3D NULL) { printf_filtered ("Memory error: %d (%s)\n", errno, safe_strerror (errno)); @@ -359,7 +363,7 @@ procfs_pidlist (char *args, int from_tty) { DIR *dp =3D NULL; struct dirent *dirp =3D NULL; - char buf[512]; + char buf[PATH_MAX]; procfs_info *pidinfo =3D NULL; procfs_debuginfo *info =3D NULL; procfs_status *status =3D NULL; @@ -367,12 +371,16 @@ procfs_pidlist (char *args, int from_tty) pid_t pid; char name[512]; struct cleanup *cleanups; + char procfs_dir[PATH_MAX]; =20 - dp =3D opendir (nto_procfs_path); + snprintf (procfs_dir, sizeof (procfs_dir), "%s%s", + (nodestr !=3D NULL) ? nodestr : "", "/proc"); + + dp =3D opendir (procfs_dir); if (dp =3D=3D NULL) { fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)", - nto_procfs_path, errno, safe_strerror (errno)); + procfs_dir, errno, safe_strerror (errno)); return; } =20 @@ -395,7 +403,9 @@ procfs_pidlist (char *args, int from_tty) do_cleanups (cleanups); return; } - snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name); + snprintf (buf, sizeof (buf), "%s%s/%s/as", + (nodestr !=3D NULL) ? nodestr : "", + "/proc", dirp->d_name); pid =3D atoi (dirp->d_name); } while (pid =3D=3D 0); @@ -406,8 +416,7 @@ procfs_pidlist (char *args, int from_tty) { fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n", buf, errno, safe_strerror (errno)); - do_cleanups (cleanups); - return; + continue; } inner_cleanup =3D make_cleanup_close (fd); =20 @@ -431,11 +440,16 @@ procfs_pidlist (char *args, int from_tty) status =3D (procfs_status *) buf; for (status->tid =3D 1; status->tid <=3D num_threads; status->tid++) { - if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) !=3D EOK - && status->tid !=3D 0) - break; - if (status->tid !=3D 0) - printf_filtered ("%s - %d/%d\n", name, pid, status->tid); + const int err + =3D devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0); + printf_filtered ("%s - %d", name, pid); + if (err =3D=3D EOK && status->tid !=3D 0) + printf_filtered ("/%d\n", status->tid); + else + { + printf_filtered ("\n"); + break; + } } =20 do_cleanups (inner_cleanup); @@ -599,9 +613,38 @@ procfs_files_info (struct target_ops *ignore) =20 printf_unfiltered ("\tUsing the running image of %s %s via %s.\n", inf->attach_flag ? "attached" : "child", - target_pid_to_str (inferior_ptid), nto_procfs_path); + target_pid_to_str (inferior_ptid), + (nodestr !=3D NULL) ? nodestr : "local node"); } =20 +/* Read executable file name for the given PID. */ + +static char * +procfs_pid_to_exec_file (struct target_ops *ops, const int pid) +{ + int proc_fd; + static char proc_path[PATH_MAX]; + ssize_t rd; + + /* Read exe file name. */ + snprintf (proc_path, sizeof (proc_path), "%s/proc/%d/exefile", + (nodestr !=3D NULL) ? nodestr : "", pid); + proc_fd =3D open (proc_path, O_RDONLY); + if (proc_fd =3D=3D -1) + return NULL; + + rd =3D read (proc_fd, proc_path, sizeof (proc_path) - 1); + close (proc_fd); + if (rd <=3D 0) + { + proc_path[0] =3D '\0'; + return NULL; + } + proc_path[rd] =3D '\0'; + return proc_path; +} + + /* Attach to process PID, then initialize for debugging it. */ static void procfs_attach (struct target_ops *ops, const char *args, int from_tty) @@ -653,8 +696,8 @@ do_attach (ptid_t ptid) struct sigevent event; char path[PATH_MAX]; =20 - snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, - ptid_get_pid (ptid)); + snprintf (path, PATH_MAX - 1, "%s%s/%d/as", + (nodestr !=3D NULL) ? nodestr : "", "/proc", ptid_get_pid (ptid)); ctl_fd =3D open (path, O_RDWR); if (ctl_fd =3D=3D -1) error (_("Couldn't open proc file %s, error %d (%s)"), path, errno, @@ -872,6 +915,40 @@ procfs_xfer_partial (struct target_ops *ops, enum targ= et_object object, { case TARGET_OBJECT_MEMORY: return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_le= n); + case TARGET_OBJECT_AUXV: + if (readbuf !=3D NULL) + { + int err; + CORE_ADDR initial_stack; + debug_process_t procinfo; + /* For 32-bit architecture, size of auxv_t is 8 bytes. */ + const unsigned int sizeof_auxv_t =3D sizeof (auxv_t); + const unsigned int sizeof_tempbuf =3D 20 * sizeof_auxv_t; + int tempread; + gdb_byte *const tempbuf =3D alloca (sizeof_tempbuf); + + if (tempbuf =3D=3D NULL) + return TARGET_XFER_E_IO; + + err =3D devctl (ctl_fd, DCMD_PROC_INFO, &procinfo, + sizeof procinfo, 0); + if (err !=3D EOK) + return TARGET_XFER_E_IO; + + /* Similar as in the case of a core file, we read auxv from + initial_stack. */ + initial_stack =3D procinfo.initial_stack; + + /* procfs is always 'self-hosted', no byte-order manipulation. */ + tempread =3D nto_read_auxv_from_initial_stack (initial_stack, tempbuf, + sizeof_tempbuf, + sizeof (auxv_t)); + tempread =3D min (tempread, len) - offset; + memcpy (readbuf, tempbuf + offset, tempread); + *xfered_len =3D tempread; + return tempread ? TARGET_XFER_OK : TARGET_XFER_EOF; + } + /* Fallthru */ default: return ops->beneath->to_xfer_partial (ops->beneath, object, annex, readbuf, writebuf, offset, len, @@ -1121,7 +1198,7 @@ procfs_create_inferior (struct target_ops *ops, char = *exec_file, } =20 args =3D xstrdup (allargs); - breakup_args (args, exec_file ? &argv[1] : &argv[0]); + breakup_args (args, (exec_file !=3D NULL) ? &argv[1] : &argv[0]); =20 argv =3D nto_parse_redirection (argv, &in, &out, &err); =20 @@ -1444,6 +1521,7 @@ init_procfs_targets (void) t->to_interrupt =3D procfs_interrupt; t->to_have_continuable_watchpoint =3D 1; t->to_extra_thread_info =3D nto_extra_thread_info; + t->to_pid_to_exec_file =3D procfs_pid_to_exec_file; =20 nto_native_ops =3D t; =20 diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c index 81ee7fb..63094e8 100644 --- a/gdb/nto-tdep.c +++ b/gdb/nto-tdep.c @@ -31,6 +31,7 @@ #include "solib-svr4.h" #include "gdbcore.h" #include "objfiles.h" +#include "symfile.h" =20 #ifdef __CYGWIN__ #include @@ -394,3 +395,89 @@ nto_initialize_signals (void) signal_pass_update (SIGPHOTON, 1); #endif } + + +/* Read AUXV from initial_stack. */ +LONGEST +nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readb= uf, + LONGEST len, size_t sizeof_auxv_t) +{ + gdb_byte targ32[4]; /* For 32 bit target values. */ + gdb_byte targ64[8]; /* For 64 bit target values. */ + CORE_ADDR data_ofs =3D 0; + ULONGEST anint; + LONGEST len_read =3D 0; + gdb_byte *buff; + enum bfd_endian byte_order; + int ptr_size; + + if (sizeof_auxv_t =3D=3D 16) + ptr_size =3D 8; + else + ptr_size =3D 4; + + /* Skip over argc, argv and envp... Comment from ldd.c: + + The startup frame is set-up so that we have: + auxv + NULL + ... + envp2 + envp1 <----- void *frame + (argc + 2) * sizeof(char *) + NULL + ... + argv2 + argv1 + argc <------ void * frame + + On entry to ldd, frame gives the address of argc on the stack. */ + /* Read argc. 4 bytes on both 64 and 32 bit arches and luckily little + * endian. So we just read first 4 bytes. */ + if (target_read_memory (initial_stack + data_ofs, targ32, 4) !=3D 0) + return 0; + + byte_order =3D gdbarch_byte_order (target_gdbarch ()); + + anint =3D extract_unsigned_integer (targ32, sizeof (targ32), byte_order); + + /* Size of pointer is assumed to be 4 bytes (32 bit arch.) */ + data_ofs +=3D (anint + 2) * ptr_size; /* + 2 comes from argc itself and + NULL terminating pointer in + argv. */ + + /* Now loop over env table: */ + anint =3D 0; + while (target_read_memory (initial_stack + data_ofs, targ64, ptr_size) + =3D=3D 0) + { + if (extract_unsigned_integer (targ64, ptr_size, byte_order) =3D=3D 0) + anint =3D 1; /* Keep looping until non-null entry is found. */ + else if (anint) + break; + data_ofs +=3D ptr_size; + } + initial_stack +=3D data_ofs; + + memset (readbuf, 0, len); + buff =3D readbuf; + while (len_read <=3D len-sizeof_auxv_t) + { + if (target_read_memory (initial_stack + len_read, buff, sizeof_auxv_= t) + =3D=3D 0) + { + /* Both 32 and 64 bit structures have int as the first field. */ + const ULONGEST a_type + =3D extract_unsigned_integer (buff, sizeof (targ32), byte_order); + + if (a_type =3D=3D AT_NULL) + break; + buff +=3D sizeof_auxv_t; + len_read +=3D sizeof_auxv_t; + } + else + break; + } + return len_read; +} + + diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h index bd85d2a..7089a12 100644 --- a/gdb/nto-tdep.h +++ b/gdb/nto-tdep.h @@ -168,4 +168,8 @@ int nto_in_dynsym_resolve_code (CORE_ADDR pc); =20 char *nto_extra_thread_info (struct target_ops *self, struct thread_info *= ); =20 +LONGEST nto_read_auxv_from_initial_stack (CORE_ADDR inital_stack, + gdb_byte *readbuf, + LONGEST len, size_t sizeof_auxv_t); + #endif --=20 1.9.1 --------------040709040403070109060802-- From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 93328 invoked by alias); 20 Oct 2015 12:43:56 -0000 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 Received: (qmail 93317 invoked by uid 89); 20 Oct 2015 12:43:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_SOFTFAIL autolearn=no version=3.3.2 X-HELO: smtp-a02.blackberry.com Received: from smtp-a02.blackberry.com (HELO smtp-a02.blackberry.com) (208.65.78.91) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 20 Oct 2015 12:43:51 +0000 Received: from mhs101cnc.rim.net ([10.65.141.79]) by mhs215cnc-app.rim.net with ESMTP; 20 Oct 2015 08:43:49 -0400 Received: from unknown (HELO [10.222.109.89]) ([10.65.140.254]) by mhs101cnc.rim.net with ESMTP; 20 Oct 2015 12:43:49 +0000 Subject: Re: [PATCH 2/4] [nto] Fixes for nto procfs. To: gdb-patches@sourceware.org References: <1444752074-878-1-git-send-email-aristovski@qnx.com> <1444752074-878-3-git-send-email-aristovski@qnx.com> <561FE53A.1050406@redhat.com> Newsgroups: gmane.comp.gdb.patches Cc: Pedro Alves From: Aleksandar Ristovski X-Enigmail-Draft-Status: N1110 Message-ID: <56263704.6000007@qnx.com> Date: Tue, 20 Oct 2015 12:43:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <561FE53A.1050406@redhat.com> Content-Type: multipart/mixed; boundary="------------040709040403070109060802" X-SW-Source: 2015-10/txt/msg00353.txt.bz2 Message-ID: <20151020124300._9IxeaMI-zXDOcFHY0uSIfAXRQCoZ8yn-k8utU1LjLY@z> This is a multi-part message in MIME format. --------------040709040403070109060802 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-length: 1663 On 15-10-15 01:41 PM, Pedro Alves wrote: > It would have been nicer to see this split into a fix/theme > per patch, and add something to the commit log about each > fix. E.g., the aux bits could easily be a separate patch. > > Anyway, this is pretty isolated to NTO bits. I'm trying to catch up and submit local changes for previous ports. While patches may not be minimalistic, I am trying to at least bring certain rounded-up improvement (e.g. having a debug session). But I will try to make more granulated patches. > > LGTM with the nits below addressed. > > On 10/13/2015 05:01 PM, Aleksandar Ristovski wrote: > >> } >> >> do_cleanups (inner_cleanup); >> @@ -599,9 +612,40 @@ procfs_files_info (struct target_ops *ignore) >> >> printf_unfiltered ("\tUsing the running image of %s %s via %s.\n", >> inf->attach_flag ? "attached" : "child", >> - target_pid_to_str (inferior_ptid), nto_procfs_path); >> + target_pid_to_str (inferior_ptid), >> + nodestr ? nodestr : "local node"); > > Write 'nodestr != NULL'. Done. Here and other places where pointer is used as a logical expression. ... >> + if (rd <= 0) >> + { >> + proc_path[0] = '\0'; >> + return NULL; >> + } >> + else >> + proc_path[rd] = '\0'; >> + >> + return proc_path; > > Either write: > > else > { > proc_path[rd] = '\0'; > return proc_path; > } > > Or drop the "else". Dropped 'else'. ... >> + >> + if (!tempbuf) >> + return TARGET_XFER_E_IO; > > if (tempbuf == NULL) > > Can NTO's alloca really return NULL? Yes. Attached fixed version of the patch. Thanks, Aleksandar Ristovski --------------040709040403070109060802 Content-Type: text/x-patch; name="0001-nto-Fixes-for-nto-procfs.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-nto-Fixes-for-nto-procfs.patch" Content-length: 13290 =46rom 62774c1deef7eb01108ac65636e2ccf974992d85 Mon Sep 17 00:00:00 2001 From: Aleksandar Ristovski Date: Mon, 5 Oct 2015 10:32:16 -0400 Subject: [PATCH] [nto] Fixes for nto procfs. gdb/ChangeLog: * nto-procfs.c (sys/auxv.h): Include. (nto_procfs_path): Rename to... (nodestr): ... this, and change type. (nto_node): Use new variable and logic accordingly. (procfs_open_1): Use new variable name. Use local buffer to construct procfs path. (procfs_pidlist): Use NODESTR to construct procfs path. (procfs_files_info): Use NODESTR to output meaningful text. (procfs_pid_to_exec_file): New target function. (do_attach): Construct procfs using NODESTR. (procfs_xfer_partial): Logic for reading TARGET_OBJECT_AUXV. (procfs_create_inferior): Compare pointer to NULL. (init_procfs_targets): Wire procfs_pid_to_exec_file. * nto-tdep.c (symfile.h): Include. (nto_read_auxv_from_initial_stack): New function. * nto-tdep.h (nto_read_auxv_from_initial_stack): New function declaration. --- gdb/nto-procfs.c | 128 ++++++++++++++++++++++++++++++++++++++++++++-------= ---- gdb/nto-tdep.c | 87 +++++++++++++++++++++++++++++++++++++ gdb/nto-tdep.h | 4 ++ 3 files changed, 194 insertions(+), 25 deletions(-) diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c index d659f79..176ceea 100644 --- a/gdb/nto-procfs.c +++ b/gdb/nto-procfs.c @@ -30,6 +30,8 @@ #include #include #include +#include + #include "gdbcore.h" #include "inferior.h" #include "target.h" @@ -73,7 +75,7 @@ static int procfs_stopped_by_watchpoint (struct target_op= s *ops); referenced elsewhere. 'nto_procfs_node' is a flag used to say whether we are local, or we should get the current node descriptor for the remote QNX node. */ -static char nto_procfs_path[PATH_MAX] =3D { "/proc" }; +static char *nodestr; static unsigned nto_procfs_node =3D ND_LOCAL_NODE; =20 /* Return the current QNX Node, or error out. This is a simple @@ -85,10 +87,11 @@ nto_node (void) { unsigned node; =20 - if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) =3D=3D 0) + if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) =3D=3D 0 + || nodestr =3D=3D NULL) return ND_LOCAL_NODE; =20 - node =3D netmgr_strtond (nto_procfs_path, 0); + node =3D netmgr_strtond (nodestr, 0); if (node =3D=3D -1) error (_("Lost the QNX node. Debug session probably over.")); =20 @@ -108,12 +111,12 @@ procfs_is_nto_target (bfd *abfd) static void procfs_open_1 (struct target_ops *ops, const char *arg, int from_tty) { - char *nodestr; char *endstr; char buffer[50]; int fd, total_size; procfs_sysinfo *sysinfo; struct cleanup *cleanups; + char nto_procfs_path[PATH_MAX]; =20 /* Offer to kill previous inferiors before opening this target. */ target_preopen (from_tty); @@ -123,8 +126,11 @@ procfs_open_1 (struct target_ops *ops, const char *arg= , int from_tty) /* Set the default node used for spawning to this one, and only override it if there is a valid arg. */ =20 + xfree (nodestr); + nodestr =3D NULL; + nto_procfs_node =3D ND_LOCAL_NODE; - nodestr =3D arg ? xstrdup (arg) : NULL; + nodestr =3D (arg !=3D NULL) ? xstrdup (arg) : NULL; =20 init_thread_list (); =20 @@ -149,10 +155,8 @@ procfs_open_1 (struct target_ops *ops, const char *arg= , int from_tty) *endstr =3D 0; } } - snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "", - "/proc"); - if (nodestr) - xfree (nodestr); + snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", + (nodestr !=3D NULL) ? nodestr : "", "/proc"); =20 fd =3D open (nto_procfs_path, O_RDONLY); if (fd =3D=3D -1) @@ -174,7 +178,7 @@ procfs_open_1 (struct target_ops *ops, const char *arg,= int from_tty) { total_size =3D sysinfo->total_size; sysinfo =3D alloca (total_size); - if (!sysinfo) + if (sysinfo =3D=3D NULL) { printf_filtered ("Memory error: %d (%s)\n", errno, safe_strerror (errno)); @@ -359,7 +363,7 @@ procfs_pidlist (char *args, int from_tty) { DIR *dp =3D NULL; struct dirent *dirp =3D NULL; - char buf[512]; + char buf[PATH_MAX]; procfs_info *pidinfo =3D NULL; procfs_debuginfo *info =3D NULL; procfs_status *status =3D NULL; @@ -367,12 +371,16 @@ procfs_pidlist (char *args, int from_tty) pid_t pid; char name[512]; struct cleanup *cleanups; + char procfs_dir[PATH_MAX]; =20 - dp =3D opendir (nto_procfs_path); + snprintf (procfs_dir, sizeof (procfs_dir), "%s%s", + (nodestr !=3D NULL) ? nodestr : "", "/proc"); + + dp =3D opendir (procfs_dir); if (dp =3D=3D NULL) { fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)", - nto_procfs_path, errno, safe_strerror (errno)); + procfs_dir, errno, safe_strerror (errno)); return; } =20 @@ -395,7 +403,9 @@ procfs_pidlist (char *args, int from_tty) do_cleanups (cleanups); return; } - snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name); + snprintf (buf, sizeof (buf), "%s%s/%s/as", + (nodestr !=3D NULL) ? nodestr : "", + "/proc", dirp->d_name); pid =3D atoi (dirp->d_name); } while (pid =3D=3D 0); @@ -406,8 +416,7 @@ procfs_pidlist (char *args, int from_tty) { fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n", buf, errno, safe_strerror (errno)); - do_cleanups (cleanups); - return; + continue; } inner_cleanup =3D make_cleanup_close (fd); =20 @@ -431,11 +440,16 @@ procfs_pidlist (char *args, int from_tty) status =3D (procfs_status *) buf; for (status->tid =3D 1; status->tid <=3D num_threads; status->tid++) { - if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) !=3D EOK - && status->tid !=3D 0) - break; - if (status->tid !=3D 0) - printf_filtered ("%s - %d/%d\n", name, pid, status->tid); + const int err + =3D devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0); + printf_filtered ("%s - %d", name, pid); + if (err =3D=3D EOK && status->tid !=3D 0) + printf_filtered ("/%d\n", status->tid); + else + { + printf_filtered ("\n"); + break; + } } =20 do_cleanups (inner_cleanup); @@ -599,9 +613,38 @@ procfs_files_info (struct target_ops *ignore) =20 printf_unfiltered ("\tUsing the running image of %s %s via %s.\n", inf->attach_flag ? "attached" : "child", - target_pid_to_str (inferior_ptid), nto_procfs_path); + target_pid_to_str (inferior_ptid), + (nodestr !=3D NULL) ? nodestr : "local node"); } =20 +/* Read executable file name for the given PID. */ + +static char * +procfs_pid_to_exec_file (struct target_ops *ops, const int pid) +{ + int proc_fd; + static char proc_path[PATH_MAX]; + ssize_t rd; + + /* Read exe file name. */ + snprintf (proc_path, sizeof (proc_path), "%s/proc/%d/exefile", + (nodestr !=3D NULL) ? nodestr : "", pid); + proc_fd =3D open (proc_path, O_RDONLY); + if (proc_fd =3D=3D -1) + return NULL; + + rd =3D read (proc_fd, proc_path, sizeof (proc_path) - 1); + close (proc_fd); + if (rd <=3D 0) + { + proc_path[0] =3D '\0'; + return NULL; + } + proc_path[rd] =3D '\0'; + return proc_path; +} + + /* Attach to process PID, then initialize for debugging it. */ static void procfs_attach (struct target_ops *ops, const char *args, int from_tty) @@ -653,8 +696,8 @@ do_attach (ptid_t ptid) struct sigevent event; char path[PATH_MAX]; =20 - snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, - ptid_get_pid (ptid)); + snprintf (path, PATH_MAX - 1, "%s%s/%d/as", + (nodestr !=3D NULL) ? nodestr : "", "/proc", ptid_get_pid (ptid)); ctl_fd =3D open (path, O_RDWR); if (ctl_fd =3D=3D -1) error (_("Couldn't open proc file %s, error %d (%s)"), path, errno, @@ -872,6 +915,40 @@ procfs_xfer_partial (struct target_ops *ops, enum targ= et_object object, { case TARGET_OBJECT_MEMORY: return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_le= n); + case TARGET_OBJECT_AUXV: + if (readbuf !=3D NULL) + { + int err; + CORE_ADDR initial_stack; + debug_process_t procinfo; + /* For 32-bit architecture, size of auxv_t is 8 bytes. */ + const unsigned int sizeof_auxv_t =3D sizeof (auxv_t); + const unsigned int sizeof_tempbuf =3D 20 * sizeof_auxv_t; + int tempread; + gdb_byte *const tempbuf =3D alloca (sizeof_tempbuf); + + if (tempbuf =3D=3D NULL) + return TARGET_XFER_E_IO; + + err =3D devctl (ctl_fd, DCMD_PROC_INFO, &procinfo, + sizeof procinfo, 0); + if (err !=3D EOK) + return TARGET_XFER_E_IO; + + /* Similar as in the case of a core file, we read auxv from + initial_stack. */ + initial_stack =3D procinfo.initial_stack; + + /* procfs is always 'self-hosted', no byte-order manipulation. */ + tempread =3D nto_read_auxv_from_initial_stack (initial_stack, tempbuf, + sizeof_tempbuf, + sizeof (auxv_t)); + tempread =3D min (tempread, len) - offset; + memcpy (readbuf, tempbuf + offset, tempread); + *xfered_len =3D tempread; + return tempread ? TARGET_XFER_OK : TARGET_XFER_EOF; + } + /* Fallthru */ default: return ops->beneath->to_xfer_partial (ops->beneath, object, annex, readbuf, writebuf, offset, len, @@ -1121,7 +1198,7 @@ procfs_create_inferior (struct target_ops *ops, char = *exec_file, } =20 args =3D xstrdup (allargs); - breakup_args (args, exec_file ? &argv[1] : &argv[0]); + breakup_args (args, (exec_file !=3D NULL) ? &argv[1] : &argv[0]); =20 argv =3D nto_parse_redirection (argv, &in, &out, &err); =20 @@ -1444,6 +1521,7 @@ init_procfs_targets (void) t->to_interrupt =3D procfs_interrupt; t->to_have_continuable_watchpoint =3D 1; t->to_extra_thread_info =3D nto_extra_thread_info; + t->to_pid_to_exec_file =3D procfs_pid_to_exec_file; =20 nto_native_ops =3D t; =20 diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c index 81ee7fb..63094e8 100644 --- a/gdb/nto-tdep.c +++ b/gdb/nto-tdep.c @@ -31,6 +31,7 @@ #include "solib-svr4.h" #include "gdbcore.h" #include "objfiles.h" +#include "symfile.h" =20 #ifdef __CYGWIN__ #include @@ -394,3 +395,89 @@ nto_initialize_signals (void) signal_pass_update (SIGPHOTON, 1); #endif } + + +/* Read AUXV from initial_stack. */ +LONGEST +nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readb= uf, + LONGEST len, size_t sizeof_auxv_t) +{ + gdb_byte targ32[4]; /* For 32 bit target values. */ + gdb_byte targ64[8]; /* For 64 bit target values. */ + CORE_ADDR data_ofs =3D 0; + ULONGEST anint; + LONGEST len_read =3D 0; + gdb_byte *buff; + enum bfd_endian byte_order; + int ptr_size; + + if (sizeof_auxv_t =3D=3D 16) + ptr_size =3D 8; + else + ptr_size =3D 4; + + /* Skip over argc, argv and envp... Comment from ldd.c: + + The startup frame is set-up so that we have: + auxv + NULL + ... + envp2 + envp1 <----- void *frame + (argc + 2) * sizeof(char *) + NULL + ... + argv2 + argv1 + argc <------ void * frame + + On entry to ldd, frame gives the address of argc on the stack. */ + /* Read argc. 4 bytes on both 64 and 32 bit arches and luckily little + * endian. So we just read first 4 bytes. */ + if (target_read_memory (initial_stack + data_ofs, targ32, 4) !=3D 0) + return 0; + + byte_order =3D gdbarch_byte_order (target_gdbarch ()); + + anint =3D extract_unsigned_integer (targ32, sizeof (targ32), byte_order); + + /* Size of pointer is assumed to be 4 bytes (32 bit arch.) */ + data_ofs +=3D (anint + 2) * ptr_size; /* + 2 comes from argc itself and + NULL terminating pointer in + argv. */ + + /* Now loop over env table: */ + anint =3D 0; + while (target_read_memory (initial_stack + data_ofs, targ64, ptr_size) + =3D=3D 0) + { + if (extract_unsigned_integer (targ64, ptr_size, byte_order) =3D=3D 0) + anint =3D 1; /* Keep looping until non-null entry is found. */ + else if (anint) + break; + data_ofs +=3D ptr_size; + } + initial_stack +=3D data_ofs; + + memset (readbuf, 0, len); + buff =3D readbuf; + while (len_read <=3D len-sizeof_auxv_t) + { + if (target_read_memory (initial_stack + len_read, buff, sizeof_auxv_= t) + =3D=3D 0) + { + /* Both 32 and 64 bit structures have int as the first field. */ + const ULONGEST a_type + =3D extract_unsigned_integer (buff, sizeof (targ32), byte_order); + + if (a_type =3D=3D AT_NULL) + break; + buff +=3D sizeof_auxv_t; + len_read +=3D sizeof_auxv_t; + } + else + break; + } + return len_read; +} + + diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h index bd85d2a..7089a12 100644 --- a/gdb/nto-tdep.h +++ b/gdb/nto-tdep.h @@ -168,4 +168,8 @@ int nto_in_dynsym_resolve_code (CORE_ADDR pc); =20 char *nto_extra_thread_info (struct target_ops *self, struct thread_info *= ); =20 +LONGEST nto_read_auxv_from_initial_stack (CORE_ADDR inital_stack, + gdb_byte *readbuf, + LONGEST len, size_t sizeof_auxv_t); + #endif --=20 1.9.1 --------------040709040403070109060802--