From patchwork Thu Jan 21 09:24:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 10495 Received: (qmail 88068 invoked by alias); 21 Jan 2016 09:24:41 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 88036 invoked by uid 89); 21 Jan 2016 09:24:41 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=camp, Descriptor, PRSTATUS, 2013-2016 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-pf0-f175.google.com Received: from mail-pf0-f175.google.com (HELO mail-pf0-f175.google.com) (209.85.192.175) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 21 Jan 2016 09:24:39 +0000 Received: by mail-pf0-f175.google.com with SMTP id e65so20669608pfe.0; Thu, 21 Jan 2016 01:24:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-type:content-disposition:user-agent; bh=WQW+jzuGax0kOt6SDgd08cENAWgAGmJJEoOyHjkaHwM=; b=a6RUk1OKjSmCh+dBg1PWHEH66vKZ7wKnmv40qKrNAspr8bDYfpP8ubLon2xyJmvn8H sU/t+IxznsYK1C4d2evt0hr7H0wu176A03vLbRMdF9GluBNJhq2qAMq5dicDO/G3sNyc MdX+KGLJZB0uPNijdQACA+4Wu5M26+S8fp5p9FlPr3CFzSmXzga+fIQeMLQ41LHbcV/a ZMp6LDCmVO2SZAq4ucE0tEwnEkZmzCJroJ7f3TNZACEmbnf4ni7sBfWv0DQLQmMl4of5 W0jCGLGuz+ev8eJi0VzblTTI3fmFI6UzbVuNaGvrspJFJtlxgar0Q6oifaAz6dF+HlXq TRhw== X-Gm-Message-State: ALoCoQnOuL1Bl5KpsTM40wXwSvCspwKHU6y0lEytRm95Rqw4awSf84HtjlPb/yGMmRpNiegnAsU2jWWOeOH5oR4gGiIDqbh7Gg== X-Received: by 10.98.79.140 with SMTP id f12mr59932423pfj.102.1453368277638; Thu, 21 Jan 2016 01:24:37 -0800 (PST) Received: from bubble.grove.modra.org (CPE-58-160-163-67.gqzg1.fli.bigpond.net.au. [58.160.163.67]) by smtp.gmail.com with ESMTPSA id cl3sm1077851pad.11.2016.01.21.01.24.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 21 Jan 2016 01:24:36 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 00A88EA0186; Thu, 21 Jan 2016 19:54:32 +1030 (ACDT) Date: Thu, 21 Jan 2016 19:54:32 +1030 From: Alan Modra To: binutils@sourceware.org, gdb-patches@sourceware.org Subject: Linux core prstatus support Message-ID: <20160121092432.GI17028@bubble.grove.modra.org> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) This and the next patch are the first steps towards making gcore support writing NT_PRSTATUS on remote/cross targets. I'm not going to commit this one and I'm hoping someone from the gdb camp will run with it as I'm going to be busy with other things in the near future. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 6a04f04..b0f5026 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2435,6 +2435,35 @@ extern char *elfcore_write_linux_prpsinfo64 extern char *elfcore_write_ppc_linux_prpsinfo32 (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *); +struct elf_internal_linux_prstatus +{ + struct elf_internal_siginfo + { + int si_signo; + int si_code; + int si_errno; + } pr_info; + int pr_cursig; + bfd_uint64_t pr_sigpend, pr_sighold; + int pr_pid, pr_ppid, pr_pgrp, pr_sid; + struct elf_internal_timeval + { + long tv_sec; + long tv_usec; + } pr_utime, pr_stime, pr_cutime, pr_cstime; + void *pr_reg; + int pr_reg_size; + int pr_fpvalid; +}; + +/* Linux/most 32-bit archs. */ +extern char *elfcore_write_linux_prstatus32 + (bfd *, char *, int *, const struct elf_internal_linux_prstatus *); + +/* Linux/most 64-bit archs. */ +extern char *elfcore_write_linux_prstatus64 + (bfd *, char *, int *, const struct elf_internal_linux_prstatus *); + extern bfd *_bfd_elf32_bfd_from_remote_memory (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type)); diff --git a/bfd/elf-linux-core.h b/bfd/elf-linux-core.h index 48fd5ae..3838ad1 100644 --- a/bfd/elf-linux-core.h +++ b/bfd/elf-linux-core.h @@ -1,4 +1,4 @@ -/* Definitions for PRPSINFO structures under ELF on GNU/Linux. +/* Definitions for PRPSINFO and PRSTATUS structures under ELF on GNU/Linux. Copyright (C) 2013-2016 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -120,4 +120,116 @@ swap_linux_prpsinfo64_out (bfd *obfd, strncpy (to->pr_psargs, from->pr_psargs, sizeof (to->pr_psargs)); } +/* PRSTATUS structs. */ + +struct elf_external_linux_prstatus32 +{ + char pr_info[12]; + char pr_cursig[2]; + char pad[2]; + char pr_sigpend[4]; + char pr_sighold[4]; + char pr_pid[4]; + char pr_ppid[4]; + char pr_pgrp[4]; + char pr_sid[4]; + char pr_utime[8]; + char pr_stime[8]; + char pr_cutime[8]; + char pr_cstime[8]; + /* Variable size "char pr_reg[]" goes here. */ + char pr_fpvalid[4]; +}; + +struct elf_external_linux_prstatus64 +{ + char pr_info[12]; + char pr_cursig[2]; + char pad[2]; + char pr_sigpend[8]; + char pr_sighold[8]; + char pr_pid[4]; + char pr_ppid[4]; + char pr_pgrp[4]; + char pr_sid[4]; + char pr_utime[16]; + char pr_stime[16]; + char pr_cutime[16]; + char pr_cstime[16]; + /* Variable size "char pr_reg[]" goes here. */ + char pr_fpvalid[4]; + char pad2[4]; +}; + +/* Helper function to copy an elf_internal_linux_prpstatus + to an elf_external_linux_prpsinfo32 in target endian. + FROM->pr_reg is already in target endian. */ + +static inline void +swap_linux_prstatus32_out (bfd *obfd, + const struct elf_internal_linux_prstatus *from, + void *to) +{ + struct elf_external_linux_prstatus32 *dest; + + dest = (struct elf_external_linux_prstatus32 *) to; + bfd_put_32 (obfd, from->pr_info.si_signo, dest->pr_info + 0); + bfd_put_32 (obfd, from->pr_info.si_code, dest->pr_info + 4); + bfd_put_32 (obfd, from->pr_info.si_errno, dest->pr_info + 8); + bfd_put_16 (obfd, from->pr_cursig, dest->pr_cursig); + memset (dest->pad, 0, sizeof (dest->pad)); + bfd_put_32 (obfd, from->pr_sigpend, dest->pr_sigpend); + bfd_put_32 (obfd, from->pr_sighold, dest->pr_sighold); + bfd_put_32 (obfd, from->pr_pid, dest->pr_pid); + bfd_put_32 (obfd, from->pr_ppid, dest->pr_ppid); + bfd_put_32 (obfd, from->pr_pgrp, dest->pr_pgrp); + bfd_put_32 (obfd, from->pr_sid, dest->pr_sid); + bfd_put_32 (obfd, from->pr_utime.tv_sec, dest->pr_utime + 0); + bfd_put_32 (obfd, from->pr_utime.tv_usec, dest->pr_utime + 4); + bfd_put_32 (obfd, from->pr_stime.tv_sec, dest->pr_stime + 0); + bfd_put_32 (obfd, from->pr_stime.tv_usec, dest->pr_stime + 4); + bfd_put_32 (obfd, from->pr_cutime.tv_sec, dest->pr_cutime + 0); + bfd_put_32 (obfd, from->pr_cutime.tv_usec, dest->pr_cutime + 4); + bfd_put_32 (obfd, from->pr_cstime.tv_sec, dest->pr_cstime + 0); + bfd_put_32 (obfd, from->pr_cstime.tv_usec, dest->pr_cstime + 4); + memcpy (dest->pr_fpvalid, from->pr_reg, from->pr_reg_size); + bfd_put_32 (obfd, from->pr_fpvalid, dest->pr_fpvalid + from->pr_reg_size); +} + +/* Helper function to copy an elf_internal_linux_prpstatus + to an elf_external_linux_prpsinfo64 in target endian. + FROM->pr_reg is already in target endian. */ + +static inline void +swap_linux_prstatus64_out (bfd *obfd, + const struct elf_internal_linux_prstatus *from, + void *to) +{ + struct elf_external_linux_prstatus64 *dest; + + dest = (struct elf_external_linux_prstatus64 *) to; + bfd_put_32 (obfd, from->pr_info.si_signo, dest->pr_info + 0); + bfd_put_32 (obfd, from->pr_info.si_code, dest->pr_info + 4); + bfd_put_32 (obfd, from->pr_info.si_errno, dest->pr_info + 8); + bfd_put_16 (obfd, from->pr_cursig, dest->pr_cursig); + memset (dest->pad, 0, sizeof (dest->pad)); + bfd_put_64 (obfd, from->pr_sigpend, dest->pr_sigpend); + bfd_put_64 (obfd, from->pr_sighold, dest->pr_sighold); + bfd_put_32 (obfd, from->pr_pid, dest->pr_pid); + bfd_put_32 (obfd, from->pr_ppid, dest->pr_ppid); + bfd_put_32 (obfd, from->pr_pgrp, dest->pr_pgrp); + bfd_put_32 (obfd, from->pr_sid, dest->pr_sid); + bfd_put_64 (obfd, from->pr_utime.tv_sec, dest->pr_utime + 0); + bfd_put_64 (obfd, from->pr_utime.tv_usec, dest->pr_utime + 8); + bfd_put_64 (obfd, from->pr_stime.tv_sec, dest->pr_stime + 0); + bfd_put_64 (obfd, from->pr_stime.tv_usec, dest->pr_stime + 8); + bfd_put_64 (obfd, from->pr_cutime.tv_sec, dest->pr_cutime + 0); + bfd_put_64 (obfd, from->pr_cutime.tv_usec, dest->pr_cutime + 8); + bfd_put_64 (obfd, from->pr_cstime.tv_sec, dest->pr_cstime + 0); + bfd_put_64 (obfd, from->pr_cstime.tv_usec, dest->pr_cstime + 8); + memcpy (dest->pr_fpvalid, from->pr_reg, from->pr_reg_size); + bfd_put_32 (obfd, from->pr_fpvalid, dest->pr_fpvalid + from->pr_reg_size); + memset (dest->pad2 + from->pr_reg_size, 0, sizeof (dest->pad2)); +} + #endif diff --git a/bfd/elf.c b/bfd/elf.c index 74c2f2d..16d315d 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -9809,6 +9809,40 @@ elfcore_write_linux_prpsinfo64 } char * +elfcore_write_linux_prstatus32 + (bfd *obfd, + char *buf, + int *bufsize, + const struct elf_internal_linux_prstatus *prstatus) +{ + size_t datasize = (prstatus->pr_reg_size + + sizeof (struct elf_external_linux_prstatus32)); + char data[1144]; + + BFD_ASSERT (sizeof (data) >= datasize); + swap_linux_prstatus32_out (obfd, prstatus, data); + return elfcore_write_note (obfd, buf, bufsize, + "CORE", NT_PRSTATUS, data, datasize); +} + +char * +elfcore_write_linux_prstatus64 + (bfd *obfd, + char *buf, + int *bufsize, + const struct elf_internal_linux_prstatus *prstatus) +{ + size_t datasize = (prstatus->pr_reg_size + + sizeof (struct elf_external_linux_prstatus64)); + char data[1144]; /* Size of ia64 prstatus. */ + + BFD_ASSERT (sizeof (data) >= datasize); + swap_linux_prstatus64_out (obfd, prstatus, data); + return elfcore_write_note (obfd, buf, bufsize, + "CORE", NT_PRSTATUS, data, datasize); +} + +char * elfcore_write_prstatus (bfd *abfd, char *buf, int *bufsiz,