From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by sourceware.org (Postfix) with ESMTPS id A61FD384F015 for ; Thu, 19 May 2022 08:30:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A61FD384F015 Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 24J68Xo3012698 for ; Thu, 19 May 2022 08:30:45 GMT Received: from phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta02.appoci.oracle.com [147.154.114.232]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3g24aak8kf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 19 May 2022 08:30:45 +0000 Received: from pps.filterd (phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (8.16.1.2/8.16.1.2) with SMTP id 24J8G5sT040842 for ; Thu, 19 May 2022 08:30:44 GMT Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2100.outbound.protection.outlook.com [104.47.55.100]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com with ESMTP id 3g22v536rc-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 19 May 2022 08:30:44 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ZcSkF4/qVA5583dUD5wlAGV5tr+dOt/ZmW5MFrXDadfEJY4cY6r5rH4bpPpxoqaX/27iPVaRsTZpVGKAfQ18VDKHXtgQelOtahEOhlxL2oCRiIiu6I9Wz4RUxGfOTs3IRENpSnKxbdVhFIvgRlrUyeNPIw4LGxpc2QS8v8Cw16yypWPaw/cwso1/fVN/YbJsBKSY1qmNfpfQpKZeg9UoLKJmhMEDGIohHRHu+UhnukXez6M0EAr84tqEPGJdbYR+yxGxhN6gQJD+6+Nc7MBeAds+ojTwRj2al2CTsoBPnQRJVODGq4QEJpv5ETpeajzByc+15vF0rWN26OI6u1rmxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Ch2oD/xDCOjWgkP0/jIAUb4CIqcvhQvGpy+FyZCAZY4=; b=VOSy2tybNZ88Sll9xhXPFfmHodKHcbt0HXbV6K6jWjxBYZxX+aGLlYi0A6MaqrOwTZSFY2IekJwtdoAbsN26MNqAZbbB76k4MxhHCWbR2RAjZcE/AsghMUThOiUgQXLnkdwuME8HoVcjxuKdjE3YPpze10Yi3iZTJxzGq1mLyPX2qisJCHNCtPjzbcHD4WVA/esjEj5OWh7V8uO5G6eKuZ6cajm9Q3bBrSrdb7OTyFAVlqgSuk2kO1DxqfwMPukMOwdt+ax2ym6PBIq+A7i+JBwaVLZt2Z1RdU3PCdcMKdYZh/r4D9R9QiM63IxB6qgZcuT6NV7nR5seLrscLbcd2A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none Received: from MWHPR1001MB2158.namprd10.prod.outlook.com (2603:10b6:301:2d::17) by DM6PR10MB3065.namprd10.prod.outlook.com (2603:10b6:5:6f::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5273.14; Thu, 19 May 2022 08:30:41 +0000 Received: from MWHPR1001MB2158.namprd10.prod.outlook.com ([fe80::c1ba:b4c:fe6f:d171]) by MWHPR1001MB2158.namprd10.prod.outlook.com ([fe80::c1ba:b4c:fe6f:d171%7]) with mapi id 15.20.5250.018; Thu, 19 May 2022 08:30:41 +0000 From: Indu Bhagat To: binutils@sourceware.org Subject: [PATCH, RFC, V2 7/8] unwinder: generate backtrace using CTF Frame format Date: Thu, 19 May 2022 01:30:23 -0700 Message-Id: <20220519083024.2709920-8-indu.bhagat@oracle.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220519083024.2709920-1-indu.bhagat@oracle.com> References: <20220519083024.2709920-1-indu.bhagat@oracle.com> Content-Transfer-Encoding: quoted-printable Content-Type: text/plain X-ClientProxiedBy: CO2PR04CA0070.namprd04.prod.outlook.com (2603:10b6:102:1::38) To MWHPR1001MB2158.namprd10.prod.outlook.com (2603:10b6:301:2d::17) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1bbbd651-fe16-4d90-051a-08da3971db64 X-MS-TrafficTypeDiagnostic: DM6PR10MB3065:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: AhPoCQ8iELqj8dJbfzilMSZRLUnJdutdBi3uKqIOjM0gDCV+07EfArTuMBQynK33hVEt+qF/GEiiXVqhGjGX3lU2/FWkZCWgUUCF/Wg4r6DGe0bSfh9a5IVYxHz3LqG4/q5X65YWHvvchnwphxn62vvO41qLrsEWKZ+IIPYLPIg107b5nTXVyllgEfGSj8PmiWzExi2Lc6CF94mWkK5Qoozem6t0ZXowCQibwrvZDomxp1RXWffKM6VwvtdRbtnbbnfoXPqvglrHvz5JAqdlthhozA1sSIR10gctMqi+CO4QoYuP1sK73O+bte4IaPlSVDCCGwcQOGIFY5bujWDu9wl/RbyGnXRs0R1mAAPYQzc3NSRD9Lce0Aqq0JGyC3rJ2dTVriLYKxhNyHL/uyTSYXBC53IeNmrMqQs/lc7h9b6CnGdoVyi+QTMWT1siHt+uZV8cKLHexyi9Jkhh5Lf+fFXo4KStqiPbwnkmKr55lb6jfxBQj3zt2OJ4BnT+SXfMRwsLk3BzSundqf+oGE6ml5kbSPmgcqXcSd36QLsy0InS9C0iRyHaQr2E4YHSJJiNfn1ZE36gAo6OkRCHElqLAl5u0sdthUOwIDU4w1xVd+43LsyXSTCoxgP0bKQcEXrRgUTSuCZ6MweP5x23w0ti4l1xM6cR2B/ib58mEfXK4XJh9SLS/VUWzxHQoXUSgPvGnzaqhdeC2BITGiX7+e0k0BQ6GW61seU3/rJwulLqD7HMQtwcPsqQIECrY8VBnWRNfU/3zFOIj7vAey4xVuaNoal+GgRLyVkkh9sMfVSNaglV35RZMn4QIPZxtvoMFFR6 X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:MWHPR1001MB2158.namprd10.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230001)(366004)(52116002)(316002)(38100700002)(66946007)(6916009)(6506007)(6666004)(66476007)(38350700002)(66556008)(36756003)(8676002)(508600001)(8936002)(44832011)(6512007)(83380400001)(30864003)(1076003)(6486002)(86362001)(5660300002)(2906002)(2616005)(186003)(26005)(2004002)(579004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?fskczXo1D3fDvPspq0Za5bFhem85RCEMsekXDd9Juxb34isN/v5jQDfC38FO?= =?us-ascii?Q?ag5T/7rUH3rv8Bt55qMiu0PlNu6KPBorY259dV8sNBeyfqcTbp6An2ROn0Zo?= =?us-ascii?Q?lkktOj5druCE5qHzAAgYh9k3b3HH1MHvwMTGbnyuQeTTKQKsHnb0s7A920ye?= =?us-ascii?Q?Mhl8gFSumknRJwwslxlUgPTKqg7gzNrxhu8X5/j4KwTJhyOqcdNkElPpAwT9?= =?us-ascii?Q?wK3PiLisUKJo0jJEUW+B4eG76Mg5NUg1Z80ZgSWo2kHisEgaM/eo2L6sresZ?= =?us-ascii?Q?b44KseobudQD0aVQj69oShw7QfgmuAU9L5NDsEuGk0K9DGqqrSqfiePjTWAr?= =?us-ascii?Q?Z1CIxCzqsMbe7Xgtv20Dj4sIeEJP+x/1zOt1oXi+4opUhF170ZwovjIDBVzQ?= =?us-ascii?Q?fMnbt6F20exh5ubQ2Vp/Hqv7IfeS5fqHTRyMpKQwoKIzACYDnRZC3wjZKC2S?= =?us-ascii?Q?Zf+80FPuWW4rYuD+32FB8ExWbw2+ZjCIKxr1LMp3L7rhDnsNRhI2kW0zhaK7?= =?us-ascii?Q?tp0l9w0pxJ1oyeFHhKx7GrIUqk0+DXxGmGs6JvnxzNZi5VQ2TdISZWcpBjFK?= =?us-ascii?Q?+tuJ2w0MiDicosWDNf/bGHrMCgoF2WQqLlA94FIYSZO4o13muwYchVxB4ydD?= =?us-ascii?Q?/LSQjVqdTK0jXFWND+JemwBJN9PvvuSnrFMj0RFZ7TYexS8p+ooK1p3tY4bq?= =?us-ascii?Q?4AFDFGuu/OmFzw88uyb9VSKzgiYro1kEgtToncBaUHypOcr2SRHHJ7oG94Jc?= =?us-ascii?Q?1XCQpJzSLauCO6CSjijhRPR81MOph40Nsly8+UkSVKtcC0+qDpXX6Kr7LwAq?= =?us-ascii?Q?wkjBDMvy76xB6nFlesl8JdyC4BioZmIJSs2GjwJsnTyPSEgx7Vo4D9In0eWi?= =?us-ascii?Q?Tt8wptrf9V3AOhNiYvWQvLd8OrJgZra20h8zfW3jBQOSLc3m0pZyZxgvK71G?= =?us-ascii?Q?ObfYA+UQBpi/1YUvRTx65WTfkPEhxu18F6TQqwzurFZr+OiyqRLqdcaOGoLs?= =?us-ascii?Q?FKEZ7Bkhz9BAm1JRXAhDZ2IoNaZu+cgiAtQ/aKowlWeSixwIljhn6RS0INhW?= =?us-ascii?Q?x+DpgnMEVHKhSmt+aarr/yQ54XEod1mIWkZf+u5RfsRfshsDT28lAYMLuxd1?= =?us-ascii?Q?+5/XxAtEGcvFWe6t/JW3Ukgjc4KhDkzYj2svANpz26k3jN6g7546i6LkESLT?= =?us-ascii?Q?P6XTXzoTLGTXPWuSQGRj4cy6dLvakxSFuB4fdwC0zWm697WC/SiqxFdsAqi6?= =?us-ascii?Q?fOmLWKCY6hfi66BmhmXy5m91PUgO+hZ/hq6FT0IPK3BlXeXSWf9Y+ry4Q4Aa?= =?us-ascii?Q?ZYoaifBjY5SaWncQZOpeLPXGDvFhm89yJr4yX3bcM4BnJAB7jutUbB+xqD7n?= =?us-ascii?Q?fws+JwiK6LfOOmQhF5NXlaBujDFt+vj1p5A7ccxSjTOfLHSEuAz+x4kMLOFP?= =?us-ascii?Q?d5RRqZxaEkCNdc4tEV8y/o9Eakxp3k6jF3I+89VKB2mry7u/civsgZHsh/eh?= =?us-ascii?Q?nv91Uym6ND1cc+vDiF/yI1NIGoGJLWCxVMO9lR9lcAEBgDAXSFw666nbRQHZ?= =?us-ascii?Q?aCxkR8d60LFIJ69GOFfI6a8pW6qSLxXty59/PGaRIZtx5D1mW8q29PSNUoMU?= =?us-ascii?Q?G4eppKRP5BokaAinSHB1l+mvBubE7izcK1cATj1/ZOpwL43Fw/rtwXtC1Pgq?= =?us-ascii?Q?CmRtnn/RqreyorjH9AHunL4nfRRuFOe8w6pagp367Cn8Hw3Ng5kM6t5dv2+1?= =?us-ascii?Q?EwtzmhLZYE7zIcPdWFfSOC1FnQhK7CY=3D?= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1bbbd651-fe16-4d90-051a-08da3971db64 X-MS-Exchange-CrossTenant-AuthSource: MWHPR1001MB2158.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 May 2022 08:30:40.3542 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: oLyHEQiYWuaHVdDPM2dudf5gcdOVIDoZS7yTv6dvftQEaGhly2NIm7phUjDrMGQb50n077nszxOvHegXgc9naA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR10MB3065 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.486, 18.0.874 definitions=2022-05-19_01:2022-05-19, 2022-05-19 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 mlxlogscore=999 spamscore=0 bulkscore=0 malwarescore=0 adultscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2202240000 definitions=main-2205190049 X-Proofpoint-ORIG-GUID: vsrrmcIF02fkyK5BHkowUQdYKc4Opbmp X-Proofpoint-GUID: vsrrmcIF02fkyK5BHkowUQdYKc4Opbmp X-Spam-Status: No, score=-13.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 May 2022 08:30:52 -0000 From: Weimin Pan [Changes from V1] - buildsystem: changes have been made to build libctfbacktrace only when --gctf-frame support is available in the assembler. These buildsystem changes are necessary because the CTF Frame based unwinder needs the CTF Frame unwind info for itself to work. [End of changes from V1] A simple unwinder based on CTF Frame format. PS: libctfframe/configure has NOT been included in the patch. Please regenerate. config/ChangeLog: * ctf-frame.m4: New file. include/ChangeLog: * ctf-backtrace-api.h: New file. ChangeLog: * libctfframe/Makefile.am: Build backtrace functionality in its own library. Install libctfbacktrace conditionally. * libctfframe/Makefile.in: Regenerate. * libctfframe/aclocal.m4: Regenerate. * libctfframe/configure: Regenerate. <-- [REMOVED FROM THE PATCH. PLEASE REGENERATE. ] * libctfframe/configure.ac: Check if gas supports --gctf-frame command line option. * libctfframe/ctf-backtrace-err.c: New file. * libctfframe/ctf-backtrace.c: New file. * libctfframe/ttest.c: New file. --- config/ctf-frame.m4 | 16 + include/ctf-backtrace-api.h | 57 +++ libctfframe/Makefile.am | 16 +- libctfframe/Makefile.in | 101 +++++- libctfframe/aclocal.m4 | 1 + libctfframe/configure.ac | 7 + libctfframe/ctf-backtrace-err.c | 46 +++ libctfframe/ctf-backtrace.c | 617 ++++++++++++++++++++++++++++++++ libctfframe/ttest.c | 78 ++++ 9 files changed, 919 insertions(+), 20 deletions(-) create mode 100644 config/ctf-frame.m4 create mode 100644 include/ctf-backtrace-api.h create mode 100644 libctfframe/ctf-backtrace-err.c create mode 100644 libctfframe/ctf-backtrace.c create mode 100644 libctfframe/ttest.c diff --git a/config/ctf-frame.m4 b/config/ctf-frame.m4 new file mode 100644 index 00000000000..100840b805f --- /dev/null +++ b/config/ctf-frame.m4 @@ -0,0 +1,16 @@ +# CTF_CHECK_AS_CTF_FRAME +# ---------------------- +# Check whether the assembler supports generation of CTF Frame +# unwind information. +# +# Defines: +# ac_cv_have_ctfframe + +AC_DEFUN([CTF_CHECK_AS_CTF_FRAME],[ + ac_save_CFLAGS=3D"$CFLAGS" + CFLAGS=3D"$CFLAGS -Wa,--gctf-frame" + AC_MSG_CHECKING([for as that supports --gctf-frame]) + AC_TRY_COMPILE([], [return 0;], [ac_cv_have_ctfframe=3Dyes], [ac_cv_have= _ctfframe=3Dno]) + AC_MSG_RESULT($ac_cv_have_ctfframe) + CFLAGS=3D"$ac_save_CFLAGS" +]) diff --git a/include/ctf-backtrace-api.h b/include/ctf-backtrace-api.h new file mode 100644 index 00000000000..7b3463d88a3 --- /dev/null +++ b/include/ctf-backtrace-api.h @@ -0,0 +1,57 @@ +/* Public API to CTF backtrace.=0D +=0D + Copyright (C) 2022 Free Software Foundation, Inc.=0D +=0D + This file is part of xxxxxx. (FIXME)=0D +=0D + This program is free software; you can redistribute it and/or modify=0D + it under the terms of the GNU General Public License as published by=0D + the Free Software Foundation; either version 3 of the License, or=0D + (at your option) any later version.=0D +=0D + This program is distributed in the hope that it will be useful,=0D + but WITHOUT ANY WARRANTY; without even the implied warranty of=0D + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0D + GNU General Public License for more details.=0D +=0D + You should have received a copy of the GNU General Public License=0D + along with this program. If not, see . = */=0D +=0D +#ifndef _CTF_BACKTRACE_API_H=0D +#define _CTF_BACKTRACE_API_H=0D +=0D +#ifdef __cplusplus=0D +extern "C"=0D +{=0D +#endif=0D +=0D +enum ctf_bt_errcode=0D +{=0D + CTF_BT_OK,=0D + CTF_BT_ERR_NOCTF,=0D + CTF_BT_ERR_PHDR,=0D + CTF_BT_ERR_ARG,=0D + CTF_BT_ERR_MALLOC,=0D + CTF_BT_ERR_REALLOC,=0D + CTF_BT_ERR_OPEN,=0D + CTF_BT_ERR_READLINK,=0D + CTF_BT_ERR_LSEEK,=0D + CTF_BT_ERR_READ,=0D + CTF_BT_ERR_GETCONTEXT,=0D + CTF_BT_ERR_DECODE,=0D + CTF_BT_ERR_CFA_OFFSET,=0D +};=0D +=0D +/* Get the backtrace of the calling program by storing return addresses=0D + in BUFFER. The SIZE argument specifies the maximum number of addresses= =0D + that can be stored in the buffer. Return the number of return addresses= =0D + collected or -1 if there is any error. */=0D +extern int ctf_backtrace (void **buffer, int size, int *errp);=0D +=0D +extern const char *ctf_bt_errmsg (enum ctf_bt_errcode ecode);=0D +=0D +#ifdef __cplusplus=0D +}=0D +#endif=0D +=0D +#endif /* _CTF_BACKTRACE_API_H */=0D diff --git a/libctfframe/Makefile.am b/libctfframe/Makefile.am index e321e071517..251d0f6ae40 100644 --- a/libctfframe/Makefile.am +++ b/libctfframe/Makefile.am @@ -23,8 +23,6 @@ AUTOMAKE_OPTIONS =3D foreign no-texinfo.tex =20 BASEDIR =3D $(srcdir)/.. INCDIR =3D $(srcdir)/../include -# include libctf for swap.h -AM_CPPFLAGS =3D -D_GNU_SOURCE -I$(srcdir) -I$(srcdir)/../include -I$(srcdi= r)/../libctf AM_CFLAGS =3D -std=3Dgnu99 @ac_libctfframe_warn_cflags@ @warn@ @c_warn@ @W= ARN_PEDANTIC@ @WERROR@ =20 if INSTALL_LIBBFD @@ -36,3 +34,17 @@ noinst_LTLIBRARIES =3D libctfframe.la endif =20 libctfframe_la_SOURCES =3D ctf-frame.c ctf-frame-dump.c ctf-frame-error.c +libctfframe_la_CPPFLAGS =3D -D_GNU_SOURCE -I$(srcdir) -I$(srcdir)/../inclu= de \ + -I$(srcdir)/../libctf + +if HAVE_CTF_FRAME_AS + libctfbacktrace_la_SOURCES =3D ctf-backtrace.c ctf-backtrace-err.c + libctfbacktrace_la_CPPFLAGS =3D -I$(srcdir) -I$(srcdir)/../include + libctfbacktrace_la_CFLAGS =3D -Wa,--gctf-frame +if INSTALL_LIBBFD + lib_LTLIBRARIES +=3D libctfbacktrace.la + include_HEADERS +=3D $(INCDIR)/ctf-backtrace-api.h +else + noinst_LTLIBRARIES +=3D libctfbacktrace.la +endif +endif diff --git a/libctfframe/Makefile.in b/libctfframe/Makefile.in index 50a720c8a99..b57c926a979 100644 --- a/libctfframe/Makefile.in +++ b/libctfframe/Makefile.in @@ -107,10 +107,14 @@ PRE_UNINSTALL =3D : POST_UNINSTALL =3D : build_triplet =3D @build@ host_triplet =3D @host@ +@HAVE_CTF_FRAME_AS_TRUE@@INSTALL_LIBBFD_TRUE@am__append_1 =3D libctfbacktr= ace.la +@HAVE_CTF_FRAME_AS_TRUE@@INSTALL_LIBBFD_TRUE@am__append_2 =3D $(INCDIR)/ct= f-backtrace-api.h +@HAVE_CTF_FRAME_AS_TRUE@@INSTALL_LIBBFD_FALSE@am__append_3 =3D libctfbackt= race.la subdir =3D . ACLOCAL_M4 =3D $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps =3D $(top_srcdir)/../bfd/acinclude.m4 \ $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/ctf-frame.m4 \ $(top_srcdir)/../config/depstand.m4 \ $(top_srcdir)/../config/jobserver.m4 \ $(top_srcdir)/../config/lead-dot.m4 \ @@ -159,14 +163,29 @@ am__uninstall_files_from_dir =3D { \ } am__installdirs =3D "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" LTLIBRARIES =3D $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) -libctfframe_la_LIBADD =3D -am_libctfframe_la_OBJECTS =3D ctf-frame.lo ctf-frame-dump.lo \ - ctf-frame-error.lo -libctfframe_la_OBJECTS =3D $(am_libctfframe_la_OBJECTS) +libctfbacktrace_la_LIBADD =3D +am__libctfbacktrace_la_SOURCES_DIST =3D ctf-backtrace.c \ + ctf-backtrace-err.c +@HAVE_CTF_FRAME_AS_TRUE@am_libctfbacktrace_la_OBJECTS =3D \ +@HAVE_CTF_FRAME_AS_TRUE@ libctfbacktrace_la-ctf-backtrace.lo \ +@HAVE_CTF_FRAME_AS_TRUE@ libctfbacktrace_la-ctf-backtrace-err.lo +libctfbacktrace_la_OBJECTS =3D $(am_libctfbacktrace_la_OBJECTS) AM_V_lt =3D $(am__v_lt_@AM_V@) am__v_lt_ =3D $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 =3D --silent am__v_lt_1 =3D=20 +libctfbacktrace_la_LINK =3D $(LIBTOOL) $(AM_V_lt) --tag=3DCC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=3Dlink $(CCLD) \ + $(libctfbacktrace_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +@HAVE_CTF_FRAME_AS_TRUE@@INSTALL_LIBBFD_FALSE@am_libctfbacktrace_la_rpath = =3D +@HAVE_CTF_FRAME_AS_TRUE@@INSTALL_LIBBFD_TRUE@am_libctfbacktrace_la_rpath = =3D \ +@HAVE_CTF_FRAME_AS_TRUE@@INSTALL_LIBBFD_TRUE@ -rpath $(libdir) +libctfframe_la_LIBADD =3D +am_libctfframe_la_OBJECTS =3D libctfframe_la-ctf-frame.lo \ + libctfframe_la-ctf-frame-dump.lo \ + libctfframe_la-ctf-frame-error.lo +libctfframe_la_OBJECTS =3D $(am_libctfframe_la_OBJECTS) @INSTALL_LIBBFD_FALSE@am_libctfframe_la_rpath =3D @INSTALL_LIBBFD_TRUE@am_libctfframe_la_rpath =3D -rpath $(libdir) AM_V_P =3D $(am__v_P_@AM_V@) @@ -203,15 +222,16 @@ AM_V_CCLD =3D $(am__v_CCLD_@AM_V@) am__v_CCLD_ =3D $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 =3D @echo " CCLD " $@; am__v_CCLD_1 =3D=20 -SOURCES =3D $(libctfframe_la_SOURCES) -DIST_SOURCES =3D $(libctfframe_la_SOURCES) +SOURCES =3D $(libctfbacktrace_la_SOURCES) $(libctfframe_la_SOURCES) +DIST_SOURCES =3D $(am__libctfbacktrace_la_SOURCES_DIST) \ + $(libctfframe_la_SOURCES) am__can_run_installinfo =3D \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -am__include_HEADERS_DIST =3D $(INCDIR)/ctf-frame.h \ - $(INCDIR)/ctf-frame-api.h +am__include_HEADERS_DIST =3D $(INCDIR)/ctf-backtrace-api.h \ + $(INCDIR)/ctf-frame.h $(INCDIR)/ctf-frame-api.h HEADERS =3D $(include_HEADERS) am__tagged_files =3D $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in @@ -368,7 +388,6 @@ pdfdir =3D @pdfdir@ prefix =3D @prefix@ program_transform_name =3D @program_transform_name@ psdir =3D @psdir@ -runstatedir =3D @runstatedir@ sbindir =3D @sbindir@ sharedstatedir =3D @sharedstatedir@ srcdir =3D @srcdir@ @@ -383,14 +402,20 @@ ACLOCAL_AMFLAGS =3D -I .. -I ../config AUTOMAKE_OPTIONS =3D foreign no-texinfo.tex BASEDIR =3D $(srcdir)/.. INCDIR =3D $(srcdir)/../include -# include libctf for swap.h -AM_CPPFLAGS =3D -D_GNU_SOURCE -I$(srcdir) -I$(srcdir)/../include -I$(srcdi= r)/../libctf AM_CFLAGS =3D -std=3Dgnu99 @ac_libctfframe_warn_cflags@ @warn@ @c_warn@ @W= ARN_PEDANTIC@ @WERROR@ -@INSTALL_LIBBFD_TRUE@lib_LTLIBRARIES =3D libctfframe.la -@INSTALL_LIBBFD_FALSE@include_HEADERS =3D=20 -@INSTALL_LIBBFD_TRUE@include_HEADERS =3D $(INCDIR)/ctf-frame.h $(INCDIR)/c= tf-frame-api.h -@INSTALL_LIBBFD_FALSE@noinst_LTLIBRARIES =3D libctfframe.la +@INSTALL_LIBBFD_TRUE@lib_LTLIBRARIES =3D libctfframe.la $(am__append_1) +@INSTALL_LIBBFD_FALSE@include_HEADERS =3D $(am__append_2) +@INSTALL_LIBBFD_TRUE@include_HEADERS =3D $(INCDIR)/ctf-frame.h \ +@INSTALL_LIBBFD_TRUE@ $(INCDIR)/ctf-frame-api.h $(am__append_2) +@INSTALL_LIBBFD_FALSE@noinst_LTLIBRARIES =3D libctfframe.la \ +@INSTALL_LIBBFD_FALSE@ $(am__append_3) libctfframe_la_SOURCES =3D ctf-frame.c ctf-frame-dump.c ctf-frame-error.c +libctfframe_la_CPPFLAGS =3D -D_GNU_SOURCE -I$(srcdir) -I$(srcdir)/../inclu= de \ + -I$(srcdir)/../libctf + +@HAVE_CTF_FRAME_AS_TRUE@libctfbacktrace_la_SOURCES =3D ctf-backtrace.c ctf= -backtrace-err.c +@HAVE_CTF_FRAME_AS_TRUE@libctfbacktrace_la_CPPFLAGS =3D -I$(srcdir) -I$(sr= cdir)/../include +@HAVE_CTF_FRAME_AS_TRUE@libctfbacktrace_la_CFLAGS =3D -Wa,--gctf-frame all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am =20 @@ -491,6 +516,9 @@ clean-noinstLTLIBRARIES: rm -f $${locs}; \ } =20 +libctfbacktrace.la: $(libctfbacktrace_la_OBJECTS) $(libctfbacktrace_la_DEP= ENDENCIES) $(EXTRA_libctfbacktrace_la_DEPENDENCIES)=20 + $(AM_V_CCLD)$(libctfbacktrace_la_LINK) $(am_libctfbacktrace_la_rpath) $(l= ibctfbacktrace_la_OBJECTS) $(libctfbacktrace_la_LIBADD) $(LIBS) + libctfframe.la: $(libctfframe_la_OBJECTS) $(libctfframe_la_DEPENDENCIES) $= (EXTRA_libctfframe_la_DEPENDENCIES)=20 $(AM_V_CCLD)$(LINK) $(am_libctfframe_la_rpath) $(libctfframe_la_OBJECTS) = $(libctfframe_la_LIBADD) $(LIBS) =20 @@ -500,9 +528,11 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c =20 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-frame-dump.Plo@am__qu= ote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-frame-error.Plo@am__q= uote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-frame.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctfbacktrace_la-ctf-ba= cktrace-err.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctfbacktrace_la-ctf-ba= cktrace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctfframe_la-ctf-frame-= dump.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctfframe_la-ctf-frame-= error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libctfframe_la-ctf-frame.= Plo@am__quote@ =20 .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.= Tpo -c -o $@ $< @@ -525,6 +555,41 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< =20 +libctfbacktrace_la-ctf-backtrace.lo: ctf-backtrace.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=3DCC $(AM_LIBTO= OLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAULT_INCLUDES)= $(INCLUDES) $(libctfbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(libctfbacktrace_l= a_CFLAGS) $(CFLAGS) -MT libctfbacktrace_la-ctf-backtrace.lo -MD -MP -MF $(D= EPDIR)/libctfbacktrace_la-ctf-backtrace.Tpo -c -o libctfbacktrace_la-ctf-ba= cktrace.lo `test -f 'ctf-backtrace.c' || echo '$(srcdir)/'`ctf-backtrace.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libctfbacktrace_la-ctf-= backtrace.Tpo $(DEPDIR)/libctfbacktrace_la-ctf-backtrace.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=3D'ctf-backtrace.c' obj= ect=3D'libctfbacktrace_la-ctf-backtrace.lo' libtool=3Dyes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=3DC= C $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAU= LT_INCLUDES) $(INCLUDES) $(libctfbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(libct= fbacktrace_la_CFLAGS) $(CFLAGS) -c -o libctfbacktrace_la-ctf-backtrace.lo `= test -f 'ctf-backtrace.c' || echo '$(srcdir)/'`ctf-backtrace.c + +libctfbacktrace_la-ctf-backtrace-err.lo: ctf-backtrace-err.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=3DCC $(AM_LIBTO= OLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAULT_INCLUDES)= $(INCLUDES) $(libctfbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(libctfbacktrace_l= a_CFLAGS) $(CFLAGS) -MT libctfbacktrace_la-ctf-backtrace-err.lo -MD -MP -MF= $(DEPDIR)/libctfbacktrace_la-ctf-backtrace-err.Tpo -c -o libctfbacktrace_l= a-ctf-backtrace-err.lo `test -f 'ctf-backtrace-err.c' || echo '$(srcdir)/'`= ctf-backtrace-err.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libctfbacktrace_la-ctf-= backtrace-err.Tpo $(DEPDIR)/libctfbacktrace_la-ctf-backtrace-err.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=3D'ctf-backtrace-err.c'= object=3D'libctfbacktrace_la-ctf-backtrace-err.lo' libtool=3Dyes @AMDEPBAC= KSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=3DC= C $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAU= LT_INCLUDES) $(INCLUDES) $(libctfbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(libct= fbacktrace_la_CFLAGS) $(CFLAGS) -c -o libctfbacktrace_la-ctf-backtrace-err.= lo `test -f 'ctf-backtrace-err.c' || echo '$(srcdir)/'`ctf-backtrace-err.c + +libctfframe_la-ctf-frame.lo: ctf-frame.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=3DCC $(AM_LIBTO= OLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAULT_INCLUDES)= $(INCLUDES) $(libctfframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) = -MT libctfframe_la-ctf-frame.lo -MD -MP -MF $(DEPDIR)/libctfframe_la-ctf-fr= ame.Tpo -c -o libctfframe_la-ctf-frame.lo `test -f 'ctf-frame.c' || echo '$= (srcdir)/'`ctf-frame.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libctfframe_la-ctf-fram= e.Tpo $(DEPDIR)/libctfframe_la-ctf-frame.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=3D'ctf-frame.c' object= =3D'libctfframe_la-ctf-frame.lo' libtool=3Dyes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=3DC= C $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAU= LT_INCLUDES) $(INCLUDES) $(libctfframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS= ) $(CFLAGS) -c -o libctfframe_la-ctf-frame.lo `test -f 'ctf-frame.c' || ech= o '$(srcdir)/'`ctf-frame.c + +libctfframe_la-ctf-frame-dump.lo: ctf-frame-dump.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=3DCC $(AM_LIBTO= OLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAULT_INCLUDES)= $(INCLUDES) $(libctfframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) = -MT libctfframe_la-ctf-frame-dump.lo -MD -MP -MF $(DEPDIR)/libctfframe_la-c= tf-frame-dump.Tpo -c -o libctfframe_la-ctf-frame-dump.lo `test -f 'ctf-fram= e-dump.c' || echo '$(srcdir)/'`ctf-frame-dump.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libctfframe_la-ctf-fram= e-dump.Tpo $(DEPDIR)/libctfframe_la-ctf-frame-dump.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=3D'ctf-frame-dump.c' ob= ject=3D'libctfframe_la-ctf-frame-dump.lo' libtool=3Dyes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=3DC= C $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAU= LT_INCLUDES) $(INCLUDES) $(libctfframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS= ) $(CFLAGS) -c -o libctfframe_la-ctf-frame-dump.lo `test -f 'ctf-frame-dump= .c' || echo '$(srcdir)/'`ctf-frame-dump.c + +libctfframe_la-ctf-frame-error.lo: ctf-frame-error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=3DCC $(AM_LIBTO= OLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAULT_INCLUDES)= $(INCLUDES) $(libctfframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) = -MT libctfframe_la-ctf-frame-error.lo -MD -MP -MF $(DEPDIR)/libctfframe_la-= ctf-frame-error.Tpo -c -o libctfframe_la-ctf-frame-error.lo `test -f 'ctf-f= rame-error.c' || echo '$(srcdir)/'`ctf-frame-error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libctfframe_la-ctf-fram= e-error.Tpo $(DEPDIR)/libctfframe_la-ctf-frame-error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=3D'ctf-frame-error.c' o= bject=3D'libctfframe_la-ctf-frame-error.lo' libtool=3Dyes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=3DC= C $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=3Dcompile $(CC) $(DEFS) $(DEFAU= LT_INCLUDES) $(INCLUDES) $(libctfframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS= ) $(CFLAGS) -c -o libctfframe_la-ctf-frame-error.lo `test -f 'ctf-frame-err= or.c' || echo '$(srcdir)/'`ctf-frame-error.c + mostlyclean-libtool: -rm -f *.lo =20 diff --git a/libctfframe/aclocal.m4 b/libctfframe/aclocal.m4 index 3a0b3426ebc..bda656c049c 100644 --- a/libctfframe/aclocal.m4 +++ b/libctfframe/aclocal.m4 @@ -1229,6 +1229,7 @@ AC_SUBST([am__untar]) =20 m4_include([../bfd/acinclude.m4]) m4_include([../config/acx.m4]) +m4_include([../config/ctf-frame.m4]) m4_include([../config/depstand.m4]) m4_include([../config/jobserver.m4]) m4_include([../config/lead-dot.m4]) diff --git a/libctfframe/configure.ac b/libctfframe/configure.ac index d5e5db3c416..cd7ed5f7cdb 100644 --- a/libctfframe/configure.ac +++ b/libctfframe/configure.ac @@ -57,6 +57,13 @@ ACX_PROG_CC_WARNING_ALMOST_PEDANTIC([-Wno-long-long]) # corrected. ACX_PROG_CC_WARNINGS_ARE_ERRORS([manual]) =20 +dnl The libctfbacktrace library needs to be built with CTF Frame info. +dnl If the build assembler is not capable of generate CTF Frame then +dnl the library is not built. + +CTF_CHECK_AS_CTF_FRAME +AM_CONDITIONAL([HAVE_CTF_FRAME_AS], [test "x$ac_cv_have_ctfframe" =3D "xye= s"]) + AM_MAINTAINER_MODE AM_INSTALL_LIBBFD ACX_PROG_CC_WARNING_OPTS([-Wall], [ac_libctfframe_warn_cflags]) diff --git a/libctfframe/ctf-backtrace-err.c b/libctfframe/ctf-backtrace-er= r.c new file mode 100644 index 00000000000..374ceaf3266 --- /dev/null +++ b/libctfframe/ctf-backtrace-err.c @@ -0,0 +1,46 @@ +/* ctf-backtrace-err.c - CTF Backtrace Error table. + + Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of libctfbacktrace. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . = */ + +#include "config.h" +#include "ctf-backtrace-api.h" + +/* CTF backtrace error messages. */ +static const char *const ctf_bt_errlist[] =3D +{ + "", + "File does not contain CTF Frame data", + "Iterating shared object reading error", + "Failed to malloc memory space", + "Failed to realloc memory space", + "Failed to open file", + "Failed on resolve canonical file name", + "Failed to reposition file offset", + "Failed to read from a file descriptor", + "Failed to get the user context", + "Failed to set up decode data", + "Illegal CFA offset" +}; + +/* ctf_bt_perror -Return the error message associated with the error code.= */ + +const char * +ctf_bt_errmsg (enum ctf_bt_errcode ecode) +{ + return ctf_bt_errlist[ecode]; +} diff --git a/libctfframe/ctf-backtrace.c b/libctfframe/ctf-backtrace.c new file mode 100644 index 00000000000..c17a8dcfffd --- /dev/null +++ b/libctfframe/ctf-backtrace.c @@ -0,0 +1,617 @@ +/* ctf-backtrace.c - The CTF Frame unwinder. + + Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of libctfbacktrace. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . = */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ansidecl.h" +#include "ctf-frame-api.h" +#include "ctf-backtrace-api.h" + +#ifndef PT_CTF_FRAME +#define PT_CTF_FRAME 0x6474e554 /* FIXME. */ +#endif + +#define _cf_printflike_(string_index,first_to_check) \ + __attribute__ ((__format__ (__printf__, (string_index), (first_to_chec= k)))) + +static int _ctf_unwind_debug; /* Control for printing out debug info. */ +static int no_of_entries =3D 32; + +/* CTF decode data for the main module or a DSO. */ +struct ctf_decode_data +{ + char *cdd_data; /* CTF decode data. */ + int cdd_data_size; /* CTF decode data size. */ + uint64_t cdd_text_vma; /* Text segment's virtual address. */ + int cdd_text_size; /* Text segment's size. */ + uint64_t cdd_ctf_vma; /* CTF segment's virtual address. */=09 + ctf_frame_decoder_ctx *cdd_ctf_ctx; /* CTF decoder context. */ +}; + +/* List that holds CTF frame info for the shared libraries. */ +struct dso_cfi_list +{ + int alloced; /* Entries allocated. */ + int used; /* Entries used. */ + struct ctf_decode_data *entry; /* DSO's decode data. */ +}; + +/* Data that's passed through ctf_frame_callback. */ +struct ctf_unwind_info +{ + int cui_fd; /* File descriptor. */ + struct ctf_decode_data cui_ctx; /* The decode data. */ + struct dso_cfi_list cui_dsos; /* The DSO list. */ +}; + +static void +ctf_unwind_init_debug (void) +{ + static int inited; + + if (!inited) + { + _ctf_unwind_debug =3D getenv ("CTF_UNWIND_DEBUG") !=3D NULL; + inited =3D 1; + } +} + +_cf_printflike_ (1, 2) +static void +debug_printf (const char *format, ...) +{ + if (_ctf_unwind_debug) + { + va_list args; + + va_start (args, format); + __builtin_vprintf (format, args); + va_end (args); + } +} + +/* ctf_bt_errno - Check if there is error code in ERRP. */ + +static int +ctf_bt_errno (int *errp) +{ + if (errp =3D=3D NULL) + return 0; + + return (*errp !=3D CTF_BT_OK); +} + +/* ctf_bt_set_errno - Store the specified error code ERROR into ERRP if + it is non-NULL. */ + +static void +ctf_bt_set_errno (int *errp, int error) +{ + if (errp !=3D NULL) + *errp =3D error; +} + +/* ctf_add_dso - Add .ctf_frame info in D_DATA, which is associated with + a dynamic shared object, to D_LIST. */ + +static void +ctf_add_dso (struct dso_cfi_list *d_list, + struct ctf_decode_data d_data, + int *errp) +{ + if (d_list->alloced =3D=3D 0) + { + d_list->entry =3D malloc (no_of_entries * sizeof (struct ctf_decode_= data)); + if (d_list->entry =3D=3D NULL) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_MALLOC); + return; + } + memset (d_list->entry, 0, + no_of_entries * sizeof (struct ctf_decode_data)); + d_list->alloced =3D no_of_entries; + } + else if (d_list->used =3D=3D d_list->alloced) + { + d_list->entry =3D realloc (d_list->entry, + (d_list->alloced + no_of_entries) * + sizeof (struct ctf_decode_data)); + if (d_list->entry =3D=3D NULL) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_REALLOC); + return; + } + + memset (&d_list->entry[d_list->alloced], 0, + no_of_entries * sizeof (struct ctf_decode_data)); + d_list->alloced +=3D no_of_entries; + } + + ctf_bt_set_errno (errp, CTF_BT_OK); + d_list->entry[d_list->used++] =3D d_data; +} + +/* ctf_free_cfi - Free up space allocated for .ctf_frame info for CF. */ + +static void +ctf_free_cfi (struct ctf_unwind_info *cf) +{ + struct dso_cfi_list *d_list; + int i; + + if (cf =3D=3D NULL) + return; + + free (cf->cui_ctx.cdd_data); + ctf_free_decoder (cf->cui_ctx.cdd_ctf_ctx); + close (cf->cui_fd); + + d_list =3D &cf-> cui_dsos; + if (d_list =3D=3D NULL) + return; + + for (i =3D 0; i < d_list->used; ++i) + { + free (d_list->entry[i].cdd_data); + ctf_free_decoder (d_list->entry[i].cdd_ctf_ctx); + } +} + +/* ctf_find_context - Find the decode data that contains ADDR from CF. + Return the pointer to the decode data or NULL. */ + +static struct ctf_decode_data * +ctf_find_context (struct ctf_unwind_info *cf, uint64_t addr) +{ + struct dso_cfi_list *d_list; + int i; + + if (cf =3D=3D NULL) + return NULL; + + if (cf->cui_ctx.cdd_text_vma < addr + && cf->cui_ctx.cdd_text_vma + cf->cui_ctx.cdd_text_size > addr) + return &cf->cui_ctx; + + d_list =3D &cf->cui_dsos; + for (i =3D 0; i < cf->cui_dsos.used; ++i) + { + if (d_list->entry[i].cdd_text_vma <=3D addr && + d_list->entry[i].cdd_text_vma + + d_list->entry[i].cdd_text_size >=3D addr) + return &d_list->entry[i]; + } + + return NULL; +} + +/* ctf_valid_addr - Check if ADDR is valid in CF. The address is considered + invalid, with regards to CTF, if it's not in any address range of the m= ain + module or any of its DSO's. Return 1 if valid, 0 otherwise. */ + +static int +ctf_valid_addr (struct ctf_unwind_info *cf, uint64_t addr) +{ + struct ctf_decode_data *cdp; + + if (cf =3D=3D NULL) + return 0; + + cdp =3D ctf_find_context (cf, addr); + return cdp ? 1 : 0; +} + +/* ctf_load_ctx - Call decoder to create and set up the ctf frame info for + either the main module or one of the DSOs from CF, based on the input + RADDR argument. Return the newly created decode context or NULL. */ + +static ctf_frame_decoder_ctx * +ctf_load_ctx (struct ctf_unwind_info *cf, uint64_t raddr) +{ + ctf_frame_decoder_ctx *nctx; + struct ctf_decode_data *cdp; + + if (cf =3D=3D NULL) + return NULL; + + cdp =3D ctf_find_context (cf, raddr); + if (cdp =3D=3D NULL) + return NULL; + + if (cdp->cdd_ctf_ctx =3D=3D NULL) + { + int err;=20 + nctx =3D ctf_frame_decode (cdp->cdd_data, cdp->cdd_data_size, &err); + if (nctx =3D=3D NULL) + return NULL; + cdp->cdd_ctf_ctx =3D nctx; + return nctx; + } + + return NULL; +} + +/* ctf_update_ctx - Check if need to do a decode context switch, based on + the input RADDR argument, from CF. A new decode context will be created + and set up if it isn't already done so. Return the new decode context in + CTX and vma in CFI_VMA. */ + +static void +ctf_update_ctx (struct ctf_unwind_info *cf, uint64_t raddr, + ctf_frame_decoder_ctx **ctx, uint64_t *cfi_vma) +{ + ctf_frame_decoder_ctx *nctx; + struct ctf_decode_data *cdp; + + cdp =3D ctf_find_context (cf, raddr); + if (cdp !=3D NULL) + { + if (cdp->cdd_ctf_ctx =3D=3D NULL) + { + int err;=20 + nctx =3D ctf_frame_decode (cdp->cdd_data, cdp->cdd_data_size, &err); + if (nctx =3D=3D NULL) + { + *ctx =3D NULL; + return; + } + cdp->cdd_ctf_ctx =3D nctx; + } + *ctx =3D cdp->cdd_ctf_ctx; + *cfi_vma =3D cdp->cdd_ctf_vma; + } +} + +/* get_contents - Return contents at ADDR from file descriptor FD. */ + +static uint64_t +get_contents (int fd, uint64_t addr, int *errp) +{ + uint64_t data; + size_t sz; + + ctf_bt_set_errno (errp, CTF_BT_OK); + if (lseek (fd, addr, SEEK_SET) =3D=3D -1) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_LSEEK); + return 0; + } + sz =3D read (fd, &data, sizeof (uint64_t)); + if (sz !=3D sizeof (uint64_t)) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_READ); + return 0; + } + + return data; +} + +/* ctf_fd_open - Open /proc image associated with the process id and return + the file descriptor. */ + +static int +ctf_fd_open (int *errp) +{ + char filename[PATH_MAX]; + pid_t pid; + int fd; + + pid =3D getpid (); + snprintf (filename, sizeof filename, "/proc/%d/task/%d/mem", pid, pid); + if ((fd =3D open (filename, O_RDONLY)) =3D=3D -1) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_OPEN); + return -1; + } + + return fd; +} + +/* ctf_frame_callback - The callback from dl_iterate_phdr with header info + in INFO. + Return CTF frame info for either the main module or a DSO in DATA. */ + +static int +ctf_frame_callback (struct dl_phdr_info *info, + size_t size ATTRIBUTE_UNUSED, + void *data) +{ + struct ctf_unwind_info *cf =3D (struct ctf_unwind_info *) data; + int p_type, i, fd, ctf_err; + ssize_t len; + uint64_t text_vma =3D 0; + int text_size =3D 0; + + if (data =3D=3D NULL || info =3D=3D NULL) + return 1; + + debug_printf ("-- name: %s %14p\n", info->dlpi_name, (void *)info->dlpi_= addr); + + for (i =3D 0; i < info->dlpi_phnum; i++) + { + debug_printf(" %2d: [%14p; memsz:%7lx] flags: 0x%x; \n", i, + (void *) info->dlpi_phdr[i].p_vaddr, + info->dlpi_phdr[i].p_memsz, + info->dlpi_phdr[i].p_flags); + + p_type =3D info->dlpi_phdr[i].p_type; + if (p_type =3D=3D PT_LOAD && info->dlpi_phdr[i].p_flags & PF_X) + { + text_vma =3D info->dlpi_addr + info->dlpi_phdr[i].p_vaddr; + text_size =3D info->dlpi_phdr[i].p_memsz; + continue; + } + if (p_type !=3D PT_CTF_FRAME) + continue; + + if (info->dlpi_name[0] =3D=3D '\0') /* the main module. */ + { + fd =3D ctf_fd_open (&ctf_err); + if (fd =3D=3D -1) + return 1; + if (lseek (fd, info->dlpi_addr + info->dlpi_phdr[i].p_vaddr, + SEEK_SET) =3D=3D -1) + { + ctf_bt_set_errno (&ctf_err, CTF_BT_ERR_LSEEK); + return 1; + } + + cf->cui_ctx.cdd_data =3D (char *) malloc (info->dlpi_phdr[i].p_memsz); + if (cf->cui_ctx.cdd_data =3D=3D NULL) + { + ctf_bt_set_errno (&ctf_err, CTF_BT_ERR_MALLOC); + return 1; + } + + len =3D read (fd, cf->cui_ctx.cdd_data, info->dlpi_phdr[i].p_memsz); + if (len =3D=3D -1 || len !=3D (ssize_t) info->dlpi_phdr[i].p_memsz) + { + ctf_bt_set_errno (&ctf_err, CTF_BT_ERR_READ); + return 1; + } + + assert (text_vma); + cf->cui_ctx.cdd_data_size =3D len; + cf->cui_ctx.cdd_ctf_vma =3D info->dlpi_addr + info->dlpi_phdr[i].p_vadd= r; + cf->cui_fd =3D fd; + cf->cui_ctx.cdd_text_vma =3D text_vma; + cf->cui_ctx.cdd_text_size =3D text_size; + text_vma =3D 0; + return 0; + } + else + { /* a dynamic shared object. */ + struct ctf_decode_data dt; + memset (&dt, 0, sizeof (struct ctf_decode_data)); + assert (cf->cui_fd); + if (lseek (cf->cui_fd, info->dlpi_addr + info->dlpi_phdr[i].p_vaddr, + SEEK_SET) =3D=3D -1) + { + ctf_bt_set_errno (&ctf_err, CTF_BT_ERR_LSEEK); + return 1; + } + + dt.cdd_data =3D (char *) malloc (info->dlpi_phdr[i].p_memsz); + if (dt.cdd_data =3D=3D NULL) + { + ctf_bt_set_errno (&ctf_err, CTF_BT_ERR_MALLOC); + return 1; + } + + len =3D read (cf->cui_fd, dt.cdd_data, info->dlpi_phdr[i].p_memsz); + if (len =3D=3D -1 || len !=3D (ssize_t) info->dlpi_phdr[i].p_memsz) + { + ctf_bt_set_errno (&ctf_err, CTF_BT_ERR_READ); + return 1; + } + + assert (text_vma); + dt.cdd_data_size =3D len; + dt.cdd_ctf_vma =3D info->dlpi_addr + info->dlpi_phdr[i].p_vaddr; + dt.cdd_text_vma =3D text_vma; + dt.cdd_text_size =3D text_size; + text_vma =3D 0; + ctf_add_dso (&cf->cui_dsos, dt, &ctf_err); + if (ctf_err !=3D CTF_BT_OK) + return 1; + return 0; + } + } + + return 0; +} + +/* ctf_frame_unwind - Unwind the stack backtrace for CF. If successful, + store the return addresses in RA_LST. The RA_SIZE argument specifies + the maximum number of return addresses that can be stored in RA_LST + and contains the number of the addresses collected. */ + +static void +ctf_frame_unwind (struct ctf_unwind_info *cf, void **ra_lst, + int *ra_size, int *errp) +{ + uint64_t cfa, return_addr, ra_stack_loc, rfp_stack_loc; + ctf_frame_decoder_ctx *ctx; + int cfa_offset, rfp_offset, errnum, i, count; + ctf_frame_row_entry fred, *frep =3D &fred; + uint64_t pc, rfp, rsp, cfi_vma; + ucontext_t context, *cp =3D &context; + + if (cf =3D=3D NULL || ra_lst =3D=3D NULL || ra_size =3D=3D NULL) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_ARG); + return; + } + + /* Get the user context for its registers. */ + if (getcontext (cp) !=3D 0) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_GETCONTEXT); + return; + } + ctf_bt_set_errno (errp, CTF_BT_OK); + +#ifdef __x86_64__ + pc =3D cp->uc_mcontext.gregs[REG_RIP]; + rsp =3D cp->uc_mcontext.gregs[REG_RSP]; + rfp =3D cp->uc_mcontext.gregs[REG_RBP]; +#else +#ifdef __aarch64__ +#define UNWIND_AARCH64_X29 29 /* 64-bit frame pointer. */ +#define UNWIND_AARCH64_X30 30 /* 64-bit link pointer. */ + pc =3D cp->uc_mcontext.pc; + rsp =3D cp->uc_mcontext.sp; + rfp =3D cp->uc_mcontext.regs[UNWIND_AARCH64_X29]; + uint64_t ra =3D cp->uc_mcontext.regs[UNWIND_AARCH64_X30]; +#endif +#endif + + /* Load and set up the decoder. */ + ctx =3D ctf_load_ctx (cf, pc); + if (ctx =3D=3D NULL) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_DECODE); + return; + } + cfi_vma =3D cf->cui_ctx.cdd_ctf_vma; + count =3D *ra_size; + + for (i =3D 0; i < count; ++i) + { + pc -=3D cfi_vma; + errnum =3D ctf_frame_find_fre (ctx, pc, frep); + if (errnum =3D=3D 0) + { + cfa_offset =3D ctf_frame_fre_get_cfa_offset (frep, &errnum); + if (errnum =3D=3D ECTF_FRAME_FREOFFSET_NOPRESENT) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_CFA_OFFSET); + return; + } + + cfa =3D ((frep->fre_info & 0x1) =3D=3D CTF_FRAME_BASE_REG_SP + ? rsp : rfp) + cfa_offset; + +#ifdef __x86_64__ + /* For x86, read the return address from cfa - 8. */ + ra_stack_loc =3D cfa - 8; + return_addr =3D get_contents (cf->cui_fd, ra_stack_loc, errp); + if (ctf_bt_errno (errp)) + return; +#else +#ifdef __aarch64__ + int ra_offset =3D ctf_frame_fre_get_ra_offset (frep, &errnum); + if (errnum =3D=3D 0) + { + ra_stack_loc =3D cfa + ra_offset; + return_addr =3D get_contents (cf->cui_fd, ra_stack_loc, errp); + if (ctf_bt_errno (errp)) + return; + } + else + return_addr =3D ra; +#endif +#endif + + /* Validate and add return address to the list. */ + if (ctf_valid_addr (cf, return_addr) =3D=3D 0) + { + i -=3D 1; + goto find_fre_ra_err; + } + if (i !=3D 0) /* exclude self. */ + ra_lst[i-1] =3D (void *)return_addr; + + /* Set up for the next frame. */ + rfp_offset =3D ctf_frame_fre_get_fp_offset (frep, &errnum); + if (errnum =3D=3D 0) + { + rfp_stack_loc =3D cfa + rfp_offset; + rfp =3D get_contents (cf->cui_fd, rfp_stack_loc, errp); + if (ctf_bt_errno (errp)) + return; + } + rsp =3D cfa; + pc =3D return_addr; + + /* Check if need to update the decoder context and vma. */ + ctf_update_ctx (cf, return_addr, &ctx, &cfi_vma); + if (ctx =3D=3D NULL) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_DECODE); + return; + } + } + else + { + i -=3D 1; + goto find_fre_ra_err; + } + } + +find_fre_ra_err: + *ra_size =3D i; +} + +/* ctf_backtrace - Main API that user program calls to get a backtrace. + The BUFFER argument provides space for the list of the return addresses + and the SIZE argument specifies the maximum number of addresses that + can be stored in the buffer. Return the number of return addresses + collected or -1 if there is any error. */ + +int +ctf_backtrace (void **buffer, int size, int *errp) +{ + struct ctf_unwind_info ctfinfo; + + ctf_unwind_init_debug (); + + memset (&ctfinfo, 0, sizeof (struct ctf_unwind_info)); + + /* find and set up the .ctf_frame sections. */ + (void) dl_iterate_phdr (ctf_frame_callback, (void *)&ctfinfo); + if (ctfinfo.cui_fd =3D=3D 0) + { + ctf_bt_set_errno (errp, CTF_BT_ERR_NOCTF); + return -1; + } + + /* Do the stack unwinding. */ + ctf_frame_unwind (&ctfinfo, buffer, &size, errp); + if (ctf_bt_errno (errp)) + return -1; + + ctf_free_cfi (&ctfinfo); + + return size; +} diff --git a/libctfframe/ttest.c b/libctfframe/ttest.c new file mode 100644 index 00000000000..c0b8434aad5 --- /dev/null +++ b/libctfframe/ttest.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include "ctf-backtrace-api.h" + +#define BT_BUF_SIZE 100 + +/* funclist for running "ttest.x 3". */ +static const char *const func_list[] =3D +{ + "myfunc3", + "()", + "myfunc", + "myfunc", + "myfunc", + "main" +}; + +void +myfunc3 (void) +{ + void *buffer[BT_BUF_SIZE]; + int j, nptrs, err; + char **strings; + + /* Call the unwinder to get an array of return addresses. */ + nptrs =3D ctf_backtrace (buffer, BT_BUF_SIZE, &err); + if (nptrs =3D=3D -1 || nptrs !=3D 6) + { + printf ("CTF error: %s\n", ctf_bt_errmsg (err)); + return; + } + + /* Get these addresses symbolically. */ + strings =3D backtrace_symbols (buffer, nptrs); + if (strings =3D=3D NULL) { + perror("backtrace_symbols"); + exit(EXIT_FAILURE); + } + + /* Verify the results. */ + for (j =3D 0; j < nptrs; j++) + if (!strstr (strings[j], func_list[j])) + break; + + free(strings); + + printf ("%s\n", j =3D=3D nptrs ? "PASS" : "FAIL"); +} + +static void /* "static" means don't export the symbol... */ +myfunc2 (void) +{ + myfunc3 (); +} + +void +myfunc (int ncalls) +{ + if (ncalls > 1) + myfunc (ncalls - 1); + else + myfunc2 (); +} + +int +main (int argc, char *argv[]) +{ + if (argc !=3D 2) { + fprintf (stderr, "%s num-calls\n", argv[0]); + exit (EXIT_FAILURE); + } + + myfunc (atoi(argv[1])); + exit (EXIT_SUCCESS); +} --=20 2.31.1