From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27707 invoked by alias); 13 Apr 2010 19:19:32 -0000 Received: (qmail 27462 invoked by uid 22791); 13 Apr 2010 19:19:30 -0000 X-SWARE-Spam-Status: No, hits=-1.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SARE_MSGID_LONG45,TW_CP X-Spam-Check-By: sourceware.org Received: from mail-vw0-f41.google.com (HELO mail-vw0-f41.google.com) (209.85.212.41) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 13 Apr 2010 19:19:25 +0000 Received: by vws14 with SMTP id 14so953176vws.0 for ; Tue, 13 Apr 2010 12:19:22 -0700 (PDT) MIME-Version: 1.0 Received: by 10.220.44.198 with HTTP; Tue, 13 Apr 2010 12:19:22 -0700 (PDT) In-Reply-To: <201004131840.o3DIeDo9001302@glazunov.sibelius.xs4all.nl> References: <20100410221943.GA9675@intel.com> <20100410222742.GA9901@intel.com> <20100411000053.GA12675@intel.com> <20100411205250.GA24158@intel.com> <20100412132225.GA5932@intel.com> <201004121823.o3CINtrD023513@glazunov.sibelius.xs4all.nl> <201004131840.o3DIeDo9001302@glazunov.sibelius.xs4all.nl> Date: Tue, 13 Apr 2010 19:19:00 -0000 Received: by 10.220.4.21 with SMTP id 21mr3347497vcp.102.1271186362599; Tue, 13 Apr 2010 12:19:22 -0700 (PDT) Message-ID: Subject: Re: PATCH: PR corefiles/11467: amd64 gdb generates corrupted 32bit core file From: "H.J. Lu" To: Mark Kettenis Cc: gdb-patches@sourceware.org, jan.kratochvil@redhat.com Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes 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: 2010-04/txt/msg00421.txt.bz2 On Tue, Apr 13, 2010 at 11:40 AM, Mark Kettenis w= rote: >> Date: Mon, 12 Apr 2010 11:50:47 -0700 >> From: "H.J. Lu" >> >> On Mon, Apr 12, 2010 at 11:23 AM, Mark Kettenis wrote: >> >> Date: Mon, 12 Apr 2010 06:22:25 -0700 >> >> From: "H.J. Lu" >> >> >> >> On Sun, Apr 11, 2010 at 01:52:50PM -0700, H.J. Lu wrote: >> >> > Hi, >> >> > >> >> > Thanks for Mark's pointer. Solution is very simple. We just need to >> >> > make sure that we call the right fill_gregset for 32bit executable >> >> > on both Linux/x86-64 and Linux/i386. =A0OK to install? >> >> > >> >> > Thanks. >> >> > >> >> > >> >> >> >> Small update to use tdep->gregset_reg_offset instead of >> >> i386_linux_gregset_reg_offset. =A0OK to install? >> > >> > No. =A0Like I explained in an earlier mail, we're not supposed to end = up >> > in fetch_gregset() in the first place. >> > >> >> fetch_gregset is always defined and used to fill .reg section in >> coredump on Linux/x86. i386-tdep.c has > > No, that's not how it's supposed to be. =A0And unless there is a bug > somewhere, this is not what happens for the 64x64 and 32x32 cases. > >> const struct regset * >> i386_regset_from_core_section (struct gdbarch *gdbarch, >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0const cha= r *sect_name, size_t sect_size) >> { >> =A0 struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); >> >> =A0 if (strcmp (sect_name, ".reg") =3D=3D 0 && sect_size =3D=3D tdep->si= zeof_gregset) >> =A0 =A0 { >> =A0 =A0 =A0 if (tdep->gregset =3D=3D NULL) >> =A0 =A0 =A0 =A0 tdep->gregset =3D regset_alloc (gdbarch, i386_supply_gre= gset, >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 i386_collect_gregset); >> =A0 =A0 =A0 return tdep->gregset; >> =A0 =A0 } >> >> For Linux, =A0tdep->sizeof_gregset !=3D the size of .reg section. > > Then there is your bug. > >> In fact, they have nothing to do with each other. sizeof_gregset >> includes SSE and AVX registers, which have offset =3D=3D -1 since they >> aren't general-purpose registers. I don't believe we should set >> tdep->gregset since general-purpose registers is a special case for >> Linux/x86. They are handled differently. I don't want to change it. > > You're wrong here. =A0This code used to work just fine. =A0And I believe > it still works fine for the 32x32 and 64x64 cases. It works in the 32x32 and 64x64 cases because sect_size !=3D tdep->sizeof_g= regset on Linux. > I see that in i386-linux-tdep.c:i386_linux_regset_sections[] specifies > the size of the regset as 144 and sets tdep->sizeof_gregset to 17 * 4 > =3D 68. =A0That can't be right. =A0Given that > amd64-linux-tdep.c:amd64_linux_regset_sections[] specifies the size as > 144 as well, I'm betting 68 is the right valaue for i386. =A0I think I tried to set it to 68 and gcore generated the incorrect coredump. > somebody got confused here, since the size of the NT_PRSTATUS note in > 32-bit core dumps happens to be 144, but the actual size of the space > reserved for storing the registers in there is smaller. > There are lfcore_write_prstatus (bfd *abfd, char *buf, int *bufsiz, long pid, int cursig, const void *gregs) { const char *note_name =3D "CORE"; const struct elf_backend_data *bed =3D get_elf_backend_data (abfd); if (bed->elf_backend_write_core_note !=3D NULL) { char *ret; ret =3D (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz, NT_PRSTATUS, pid, cursig, gregs); if (ret !=3D NULL) return ret; } #if defined (HAVE_PRSTATUS32_T) if (bed->s->elfclass =3D=3D ELFCLASS32) { prstatus32_t prstat; memset (&prstat, 0, sizeof (prstat)); prstat.pr_pid =3D pid; prstat.pr_cursig =3D cursig; memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); return elfcore_write_note (abfd, buf, bufsiz, note_name, NT_PRSTATUS, &prstat, sizeof (prstat)); } else #endif { prstatus_t prstat; memset (&prstat, 0, sizeof (prstat)); prstat.pr_pid =3D pid; prstat.pr_cursig =3D cursig; memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); return elfcore_write_note (abfd, buf, bufsiz, note_name, NT_PRSTATUS, &prstat, sizeof (prstat)); } } tdep->sizeof_gregset =3D=3D sizeof (prstat.pr_reg) and *bufize is the section size: (gdb) gcore good Breakpoint 3, elfcore_write_prstatus (abfd=3D0xc49230, buf=3D0xc727e0 "\005= ", bufsiz=3D0x7fffffffdb2c, pid=3D15819, cursig=3D5, gregs=3D0x7fffffffd6b= 0) at /export/gnu/import/git/gdb/bfd/elf.c:8644 8644 { (top-gdb) p *bufsiz $1 =3D 144 (top-gdb) Checking sect_size =3D=3D tdep->sizeof_gregset doesn't make any senses on Linux. It doesn't make any senses to any OSes with struct elf_prstatus32 { struct elf_siginfo pr_info; /* Info associated with signal. */ short int pr_cursig; /* Current signal. */ unsigned int pr_sigpend; /* Set of pending signals. */ unsigned int pr_sighold; /* Set of held signals. */ __pid_t pr_pid; __pid_t pr_ppid; __pid_t pr_pgrp; __pid_t pr_sid; struct prstatus32_timeval pr_utime; /* User time. */ struct prstatus32_timeval pr_stime; /* System time. */ struct prstatus32_timeval pr_cutime; /* Cumulative user time. */ struct prstatus32_timeval pr_cstime; /* Cumulative system time. = */ elf_gregset32_t pr_reg; /* GP registers. */ int pr_fpvalid; /* True if math copro being used. = */ }; where elf_gregset32_t pr_reg; /* GP registers. */ is in the middle of NT_PRSTATUS section. --=20 H.J.