From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 1CGYLSjElWrvKBgAWB0awg (envelope-from ) for ; Mon, 31 Aug 2026 14:12:56 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=k+5sv5tE; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=1FybBOrP; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=WuMgff0W; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=PDj7Hj9W; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id A09C71E033; Mon, 31 Aug 2026 14:12:56 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id A0A0C1E033 for ; Mon, 31 Aug 2026 14:12:52 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A967C4BA23E2 for ; Mon, 31 Aug 2026 18:12:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A967C4BA23E2 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=k+5sv5tE; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=1FybBOrP; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=WuMgff0W; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=PDj7Hj9W Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by sourceware.org (Postfix) with ESMTPS id 2AEC34BA23EB for ; Mon, 31 Aug 2026 18:07:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2AEC34BA23EB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2AEC34BA23EB Authentication-Results: sourceware.org; arc=none smtp.remote-ip=195.135.223.130 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788199626; cv=none; b=qyy1OGquXL52j9I5omLK8Efo2BtGcrUmBnY4pRUq8SwV0KYTfgPf+PvGWnZrUu95oFVYnAQqyaeZ57J0FuxulNf6CbGfGUDag05GTLrTE3Se/cWFCsnpnhtmIOKskKs2Vt6dO2BaHsFIyGmqgV2yaM7Hex+4u1bRbR23bffcGfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788199626; c=relaxed/simple; bh=Pvp6WpDiT4oiwDOo0MJ4QwjRl9/7ZKcGq2E40GYp3j4=; h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature:From: To:Subject:Date:Message-ID:MIME-Version; b=PVgdGr1u7UrSadg5Ju0R5miZG1916aTliy95MR5RSgeRo1COd/eviFkt6NxNOwmQxPw7gT5C+/Or0zTp+5h74OpwgW4FhiOEBky3JaL/l545sBCvitZ+GZLWaXcEfx/BbL4RPTPvWs088/nzI+IPWXIB6y7fwy10xBt5NXqak84= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=k+5sv5tE; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=1FybBOrP; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=WuMgff0W; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=PDj7Hj9W DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2AEC34BA23EB Received: from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org [IPv6:2a07:de40:b281:104:10:150:64:97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 47E912272C for ; Mon, 31 Aug 2026 18:06:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1788199620; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=SEPZxgXQJpO0lieogksEIACSnvgmQXUB0jKhHpCXnW4=; b=k+5sv5tE9CiE09uME0sR1xM1+Hlw6JlGJ8OBGYNWRN99Ie6DOrijrjXf4dGRXmz+hajls4 YGNCchIeLPd9QhdMPYWW8IGV1rqH4TJxr90Mmxx4Hjh6YRnaxiBp4FkAmkpBHH01yt/Gw4 tdHWBIsGzhFeaGcG29vftqiQ5AycvW4= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1788199620; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=SEPZxgXQJpO0lieogksEIACSnvgmQXUB0jKhHpCXnW4=; b=1FybBOrP53JfmT8ktlDjqFM0FoehRyqoEflyevCA3/yC9qG5eo9EAvC8kwzqbJlYfOhvo3 sNeJTcL48GSjV5CQ== Authentication-Results: smtp-out1.suse.de; dkim=pass header.d=suse.de header.s=susede2_rsa header.b=WuMgff0W; dkim=pass header.d=suse.de header.s=susede2_ed25519 header.b=PDj7Hj9W DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1788199616; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=SEPZxgXQJpO0lieogksEIACSnvgmQXUB0jKhHpCXnW4=; b=WuMgff0WFmbDiCRP1LtvxB3Pr0MwKpM3fZMpZtlDjdUxyJYgD0kGKWo0ild795UusYZIfw QazfcFg6y73pWteQc2mT+/g5A0d6tP8PRyG+cJTtGmRLdmD+ENskhJTlzm/lebXAYTKorh 0fQvkY6TaPhoSsElju0fV9Ptk5YBsko= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1788199616; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=SEPZxgXQJpO0lieogksEIACSnvgmQXUB0jKhHpCXnW4=; b=PDj7Hj9WjnD/d9a5VJ+lne5N5Ktn/ySW6ZC7TQvNr/kkXXu63nHRQL/NnPgQi2EKRwwVcD sDgY15I1pih3woCQ== Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id DED4613685 for ; Mon, 31 Aug 2026 18:06:55 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id 1ZEdNL/ClWrqUAAAD6G6ig (envelope-from ) for ; Mon, 31 Aug 2026 18:06:55 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH] [gdb/testsuite] Remove lib/pdtrace.in Date: Mon, 31 Aug 2026 20:06:54 +0200 Message-ID: <20260831180654.1075392-1-tdevries@suse.de> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Rspamd-Action: no action X-Rspamd-Server: rspamd2.dmz-prg2.suse.org X-Rspamd-Queue-Id: 47E912272C X-Spamd-Result: default: False [-3.01 / 50.00]; BAYES_HAM(-3.00)[100.00%]; NEURAL_HAM_LONG(-1.00)[-1.000]; MID_CONTAINS_FROM(1.00)[]; R_MISSING_CHARSET(0.50)[]; R_DKIM_ALLOW(-0.20)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; NEURAL_HAM_SHORT(-0.20)[-1.000]; MIME_GOOD(-0.10)[text/plain]; MX_GOOD(-0.01)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; ARC_NA(0.00)[]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; PREVIOUSLY_DELIVERED(0.00)[gdb-patches@sourceware.org]; RCVD_TLS_ALL(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[gnu.org:url,suse.de:dkim,suse.de:mid,imap1.dmz-prg2.suse.org:rdns,imap1.dmz-prg2.suse.org:helo]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; RECEIVED_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[2a07:de40:b281:106:10:150:64:167:received]; TO_DN_NONE(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; MIME_TRACE(0.00)[0:+]; DKIM_TRACE(0.00)[suse.de:+] X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org The test-case gdb.base/dtrace-probe.exp is written to test GDB's DTrace probe support. It uses a proc dtrace_build_usdt_test_program which is defined in lib/dtrace.exp. The proc defines the following fallback: ... # Note that if DTrace is not found in the host system then this # function uses the pdtrace implementation, which is located at # testsuite/lib/pdtrace. ... proc dtrace_build_usdt_test_program {} { ... # Make sure that dtrace is installed, it is the real one (not the # script installed by SystemTap, for example) and of the right # version (>= 0.4.0). If it is not then use pdtrace instead. set dtrace "dtrace" set result [remote_exec host "$dtrace -V"] if {[lindex $result 0] != 0 \ || ![regexp {^dtrace: Sun D [0-9]\.[0-9]\.[0-9]} [lindex $result 1]]} { set dtrace "${objdir}/lib/pdtrace" } ... On my system, the fallback is activated, but then runs into trouble: - warning: dtrace-probe-p.o: \ missing .note.GNU-stack section implies executable stack - error in dtrace-probe.o(.eh_frame); no .eh_frame_hdr table will be created - undefined reference to `main' I managed to fix the first two using: - f_gen_asm '.section .note.GNU-stack,"",@progbits' - additional_flags=-fno-asynchronous-unwind-tables but the third seems to be caused by this bit: ... # Finally, we have to remove the __dtrace_* and __dtraceenabled_* # symbols from the object file, along with their respective # relocations. # # Note that the most obvious call: # strip -v -N whatever -w foo.o # will not work: # strip: not stripping symbol `whatever' because it is named in a relocation # # Fortunately using `-K !whatever' instead tricks strip to do the # right thing, but this is black magic and may eventually stop # working... $STRIP -K '!__dtrace_*' -w $objfile $STRIP -K '!__dtraceenabled_*' -w $objfile ... This is meant to strip a few symbols, but it also strips away main, which it's not supposed to do. It's not clear to me how this is supposed to be done safely. I tried out a few approaches using objcopy: - using --strip-symbol - using --redefine-sym - using--remove-section=.rela.text and only using the last one I managed to get an executable, but then ran into: ... (gdb) info probes dtrace^M No probes matched.^M (gdb) FAIL: $exp: info probes dtrace ... Given the amount of complexity present in the fallback, it is a bit unfortunate that the test-case hasn't been setup from the start to exercise the fallback always, also if a system version is available, and produce a FAIL if it's failing but supposed to work. That way we might have noticed when the fallback broke (assuming it worked as expected from the start). Anyway, given the "magic" comment I'm not putting more time into trying to fix this, and since it makes no sense to maintain a broken script, I propose to remove it. Remove lib/pdtrace.in and related references. I left a note at the point were we'd use the fallback, as a pointer in case somebody wants to reinstate and fix it. The test-case should still pass on a platform providing a system dtrace. AFAICT from searching the web, Oracle Linux would be a good setup to try. Tested on x86_64-linux. --- gdb/contrib/check-file-mode.sh | 3 +- gdb/contrib/shellcheck.sh | 3 +- gdb/pyproject.toml | 1 - gdb/testsuite/.gitignore | 1 - gdb/testsuite/Makefile.in | 5 +- gdb/testsuite/configure | 46 -- gdb/testsuite/configure.ac | 7 - gdb/testsuite/lib/dtrace.exp | 10 +- gdb/testsuite/lib/pdtrace.in | 1033 -------------------------------- 9 files changed, 7 insertions(+), 1102 deletions(-) delete mode 100755 gdb/testsuite/lib/pdtrace.in diff --git a/gdb/contrib/check-file-mode.sh b/gdb/contrib/check-file-mode.sh index a6e05535e73..5a9b0e89fbe 100755 --- a/gdb/contrib/check-file-mode.sh +++ b/gdb/contrib/check-file-mode.sh @@ -27,8 +27,7 @@ for f in "$@"; do | gdb/gcore-1.in \ | gdb/po/gdbtext \ | gdb/make-init-c \ - | gdb/testsuite/lib/notty-wrap \ - | gdb/testsuite/lib/pdtrace.in ) + | gdb/testsuite/lib/notty-wrap ) continue ;; *) diff --git a/gdb/contrib/shellcheck.sh b/gdb/contrib/shellcheck.sh index 2a0425eeaab..ad59e2b0871 100755 --- a/gdb/contrib/shellcheck.sh +++ b/gdb/contrib/shellcheck.sh @@ -45,8 +45,7 @@ for f in "$@"; do | gdb/config/djgpp/djconfig.sh \ | gdb/contrib/gdb-add-index.sh \ | gdb/gdb_buildall.sh \ - | gdb/gdb_mbuild.sh \ - | gdb/testsuite/lib/pdtrace.in) + | gdb/gdb_mbuild.sh ) # Skip unclean files. continue ;; diff --git a/gdb/pyproject.toml b/gdb/pyproject.toml index 80a106b7183..47704bb0048 100644 --- a/gdb/pyproject.toml +++ b/gdb/pyproject.toml @@ -135,7 +135,6 @@ skip = [ 'gdb/testsuite/gdb.trace/unavailable-dwarf-piece.c', 'gdb/testsuite/lib/gdb.exp', 'gdb/testsuite/lib/gdb-utils.exp', -'gdb/testsuite/lib/pdtrace.in', 'gdb/testsuite/lib/rust-support.exp' # codespell:ignore-end ] diff --git a/gdb/testsuite/.gitignore b/gdb/testsuite/.gitignore index 46265dcc003..acbc215a5ec 100644 --- a/gdb/testsuite/.gitignore +++ b/gdb/testsuite/.gitignore @@ -1,5 +1,4 @@ /Makefile -/lib/pdtrace /outputs /expect-read1 diff --git a/gdb/testsuite/Makefile.in b/gdb/testsuite/Makefile.in index 44c710f8de9..9837ee15086 100644 --- a/gdb/testsuite/Makefile.in +++ b/gdb/testsuite/Makefile.in @@ -410,15 +410,12 @@ clean mostlyclean: distclean maintainer-clean realclean: clean -rm -f *~ core - -rm -f Makefile config.status *-init.exp lib/pdtrace + -rm -f Makefile config.status *-init.exp -rm -fr *.log summary detail *.plog *.sum *.psum site.* Makefile : Makefile.in config.status $(host_makefile_frag) $(SHELL) config.status Makefile -lib/pdtrace: pdtrace.in config.status - $(SHELL) config.status lib/pdtrace - config.status: configure $(SHELL) config.status --recheck diff --git a/gdb/testsuite/configure b/gdb/testsuite/configure index 6ea9686516d..fc8cd9714c8 100755 --- a/gdb/testsuite/configure +++ b/gdb/testsuite/configure @@ -622,10 +622,6 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS LIBOBJS -NM_TRANSFORM_NAME -GAS_TRANSFORM_NAME -READELF_TRANSFORM_NAME -STRIP_TRANSFORM_NAME EXTRA_RULES EGREP GREP @@ -3449,8 +3445,6 @@ if test "${build}" = "${host}" -a "${host}" = "${target}"; then fi -# Transform the name of some programs and generate the lib/pdtrace -# test tool. test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. @@ -3461,40 +3455,6 @@ test "$program_suffix" != NONE && ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - - gdb_ac_transform=`echo "$program_transform_name" | sed -e 's/\\$\\$/\\$/g'` - STRIP_TRANSFORM_NAME=`echo strip | sed -e "$gdb_ac_transform"` - if test "x$STRIP_TRANSFORM_NAME" = x; then - STRIP_TRANSFORM_NAME=strip - fi - - - - gdb_ac_transform=`echo "$program_transform_name" | sed -e 's/\\$\\$/\\$/g'` - READELF_TRANSFORM_NAME=`echo readelf | sed -e "$gdb_ac_transform"` - if test "x$READELF_TRANSFORM_NAME" = x; then - READELF_TRANSFORM_NAME=readelf - fi - - - - gdb_ac_transform=`echo "$program_transform_name" | sed -e 's/\\$\\$/\\$/g'` - GAS_TRANSFORM_NAME=`echo as | sed -e "$gdb_ac_transform"` - if test "x$GAS_TRANSFORM_NAME" = x; then - GAS_TRANSFORM_NAME=as - fi - - - - gdb_ac_transform=`echo "$program_transform_name" | sed -e 's/\\$\\$/\\$/g'` - NM_TRANSFORM_NAME=`echo nm | sed -e "$gdb_ac_transform"` - if test "x$NM_TRANSFORM_NAME" = x; then - NM_TRANSFORM_NAME=nm - fi - - -ac_config_files="$ac_config_files lib/pdtrace" - ac_config_files="$ac_config_files Makefile" @@ -4203,7 +4163,6 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in - "lib/pdtrace") CONFIG_FILES="$CONFIG_FILES lib/pdtrace" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; @@ -4618,11 +4577,6 @@ which seems to be undefined. Please make sure it is defined" >&2;} esac - - case $ac_file$ac_mode in - "lib/pdtrace":F) chmod +x lib/pdtrace ;; - - esac done # for ac_tag diff --git a/gdb/testsuite/configure.ac b/gdb/testsuite/configure.ac index 6eae19656df..c8401741140 100644 --- a/gdb/testsuite/configure.ac +++ b/gdb/testsuite/configure.ac @@ -86,14 +86,7 @@ if test "${build}" = "${host}" -a "${host}" = "${target}"; then fi AC_SUBST(EXTRA_RULES) -# Transform the name of some programs and generate the lib/pdtrace -# test tool. AC_ARG_PROGRAM -GDB_AC_TRANSFORM(strip, STRIP_TRANSFORM_NAME) -GDB_AC_TRANSFORM(readelf, READELF_TRANSFORM_NAME) -GDB_AC_TRANSFORM(as, GAS_TRANSFORM_NAME) -GDB_AC_TRANSFORM(nm, NM_TRANSFORM_NAME) -AC_CONFIG_FILES([lib/pdtrace], [chmod +x lib/pdtrace]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/gdb/testsuite/lib/dtrace.exp b/gdb/testsuite/lib/dtrace.exp index 29449e2a9c8..e826e29e75b 100644 --- a/gdb/testsuite/lib/dtrace.exp +++ b/gdb/testsuite/lib/dtrace.exp @@ -22,10 +22,6 @@ # 3. Generate an object file containing a DOF program using dtrace -G. # 4. Link everything together to get the test program. # -# Note that if DTrace is not found in the host system then this -# function uses the pdtrace implementation, which is located at -# testsuite/lib/pdtrace. -# # This function requires 'testfile', 'srcfile' and 'binfile' to be # properly set. # @@ -35,11 +31,13 @@ proc dtrace_build_usdt_test_program {} { # Make sure that dtrace is installed, it is the real one (not the # script installed by SystemTap, for example) and of the right - # version (>= 0.4.0). If it is not then use pdtrace instead. + # version (>= 0.4.0). set dtrace "dtrace" set result [remote_exec host "$dtrace -V"] if {[lindex $result 0] != 0 || ![regexp {^dtrace: Sun D [0-9]\.[0-9]\.[0-9]} [lindex $result 1]]} { - set dtrace "${objdir}/lib/pdtrace" + # We used to use fall back here to a local implementation called + # pdtrace. + return -1 } set dscript_file "${srcdir}/${subdir}/${testfile}.d" diff --git a/gdb/testsuite/lib/pdtrace.in b/gdb/testsuite/lib/pdtrace.in deleted file mode 100755 index e41a8133c74..00000000000 --- a/gdb/testsuite/lib/pdtrace.in +++ /dev/null @@ -1,1033 +0,0 @@ -#!/bin/sh - -# A Poor (but Free) Man's dtrace -# -# Copyright (C) 2014-2026 Free Software Foundation, Inc. -# -# Contributed by Oracle, Inc. -# -# This file is part of GDB. -# -# 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 -# . - -# DISCLAIMER DISCLAIMER DISCLAIMER -# This script is a test tool. As such it is in no way intended to -# replace the "real" dtrace command for any practical purpose, apart -# from testing the DTrace USDT probes support in GDB. - -# that said... -# -# pdtrace is a limited dtrace program, implementing a subset of its -# functionality: -# -# - The generation of an ELF file containing an embedded dtrace -# program. Equivalent to dtrace -G. -# -# - The generation of a header file with definitions for static -# probes. Equivalent to dtrace -h. -# -# This allows to generate DTrace static probes without having to use -# the user-level DTrace components. The generated objects are 100% -# compatible with DTrace and can be traced by the dtrace kernel module -# like if they were generated by dtrace. -# -# Some of the known limitations of this implementation are: -# - The input d-script must describe one provider, and only one. -# - The "probe " directives in the d-file must not include argument -# names, just the types. Thus something like `char *' is valid, but -# `char *name' is not. -# - The command line options must precede other arguments, since the -# script uses the (more) portable getopts. -# - Each probe header in the d-script must be contained in -# a single line. -# - strip -K removes the debugging information from the input object -# file. -# - The supported target platforms are i[3456]86 and x86_64. -# -# Please keep this code as portable as possible. Restrict yourself to -# POSIX sh. - -# This script uses the following external programs, defined in -# variables. Some of them are substituted by autoconf. - -TR=tr -NM=@NM_TRANSFORM_NAME@ -EGREP=egrep -SED=sed -CUT=cut -READELF=@READELF_TRANSFORM_NAME@ -SORT=sort -EXPR=expr -WC=wc -UNIQ=uniq -HEAD=head -SEQ=seq -AS=@GAS_TRANSFORM_NAME@ -STRIP=@STRIP_TRANSFORM_NAME@ -TRUE=true - -# Sizes for several DOF structures, in bytes. -# -# See linux/dtrace/dof.h for the definition of the referred -# structures. - -dof_hdrsize=64 # sizeof(dtrace_dof_hdr) -dof_secsize=32 # sizeof(dtrace_dof_sect) -dof_probesize=48 # sizeof(dtrace_dof_probe) -dof_providersize=44 # sizeof(dtrace_dof_provider) - -# Types for the several DOF sections. -# -# See linux/dtrace/dof_defines.h for a complete list of section types -# along with their values. - -dof_sect_type_strtab=8 -dof_sect_type_provider=15 -dof_sect_type_probes=16 -dof_sect_type_prargs=17 -dof_sect_type_proffs=18 -dof_sect_type_prenoffs=26 - -### Functions - -# Write a message to the standard error output and exit with an error -# status. -# -# Arguments: -# $1 error message. - -f_panic() -{ - echo "error: $1" 1>&2; exit 1 -} - -# Write a usage message to the standard output and exit with an error -# status. - -f_usage() -{ - printf "Usage: pdtrace [-32|-64] [-GhV] [-o output] [-s script] [ args ... ]\n\n" - - printf "\t-32 generate 32-bit ELF files\n" - printf "\t-64 generate 64-bit ELF files\n\n" - - printf "\t-G generate an ELF file containing embedded dtrace program\n" - printf "\t-h generate a header file with definitions for static probes\n" - printf "\t-o set output file\n" - printf "\t-s handle probes according to the specified D script\n" - printf "\t-V report the DTrace API version implemented by the tool\n" - exit 2 -} - -# Write a version message to the standard output and exit with a -# successful status. - -f_version() -{ - echo "pdtrace: Sun D 1.6.3" - exit -} - -# Add a new record to a list and return it. -# -# Arguments: -# $1 is the list. -# $2 is the new record - -f_add_record() -{ - rec=$1 - test -n "$rec" && \ - { rec=$(printf %s\\n "$rec"; echo x); rec=${rec%x}; } - printf %s "$rec$2" -} - -# Collect the providers and probes information from the input object -# file. -# -# This function sets the values of the following global variables. -# The values are structured in records, each record in a line. The -# fields of each record are separated in some cases by white -# characters and in other cases by colon (:) characters. -# -# The type codes in the line format descriptors are: -# S: string, D: decimal number -# -# probes -# Regular probes and is-enabled probes. -# TYPE(S) PROVIDER(S) NAME(S) OFFSET(D) BASE(D) BASE_SYM(S) -# base_probes -# Base probes, i.e. probes sharing provider, name and container. -# PROVIDER(S) NAME(S) BASE(D) BASE_SYM(S) -# providers -# List of providers. -# PROVIDER(S) -# All the offsets are expressed in bytes. -# -# Input globals: -# objfile -# Output globals: -# probes, base_probes, providers - -probes= -base_probes= -providers= -probes_args= - -f_collect_probes() -{ - # Probe points are function calls to undefined functions featuring - # distinct names for both normal probes and is-enabled probes. - PROBE_REGEX="(__dtrace_([a-zA-Z_]+)___([a-zA-Z_]+))" - EPROBE_REGEX="(__dtraceenabled_([a-zA-Z_]+)___([a-zA-Z_]+))" - - while read type symbol provider name; do - test -z "$type" && f_panic "No probe points found in $objfile" - - provider=$(printf %s $provider | $TR -s _) - name=$(printf %s $name | $TR -s _) - - # Search the object file for relocations defined for the - # probe symbols. Then calculate the base address of the - # probe (along with the symbol associated with that base - # address) and the offset of the probe point. - for offset in $($READELF -W -r $objfile | $EGREP $symbol | $CUT -d' ' -f1) - do - # Figure out the base address for the probe. This is - # done finding the function name in the text section of - # the object file located above the probed point. But - # note that the relocation is for the address operand of - # the call instruction, so we have to subtract 1 to find - # the real probed point. - offset=$((0x$offset - 1)) - - # The addresses of is-enabled probes must point to the - # first NOP instruction in their patched instructions - # sequences, so modify them (see f_patch_objfile for the - # instruction sequences). - if test "$type" = "e"; then - if test "$objbits" -eq "32"; then - offset=$((offset + 2)) - else # 64 bits - offset=$((offset + 3)) - fi - fi - - # Determine the base address of the probe and its - # corresponding function name. - funcs=$($NM -td $objfile | $EGREP "^[0-9]+ T " \ - | $CUT -d' ' -f1,3 | $SORT -n -r | $TR ' ' :) - for fun in $funcs; do - func_off=$(printf %s $fun | $CUT -d: -f1) - func_sym=$(printf %s $fun | $CUT -d: -f2) - # Note that `expr' is used to remove leading zeros - # to avoid FUNC_OFF to be interpreted as an octal - # number in arithmetic contexts. - test "$func_off" -le "$offset" && \ - { base=$($EXPR $func_off + 0); break; } - done - test -n "$base" || \ - f_panic "could not find base address for probe at $objfile($o)" - - # Emit the record for the probe. - probes=$(f_add_record "$probes" \ - "$type $provider $name $(($offset - $base)) $base $func_sym") - done - done < loadable section. - f_gen_asm ".4byte 1\t/* uint32_t dofs_flags */" - f_gen_asm ".4byte $4\t/* uint32_t dofs_entsize */" - f_gen_asm ".8byte $5\t/* uint64_t dofs_offset */" - f_gen_asm ".8byte $6\t/* uint64_t dofs_size */" -} - -# Generate a DOF program and assembly it in the output file. -# -# The DOF program generated by this function has the following -# structure: -# -# HEADER -# STRTAB OFFTAB EOFFTAB [PROBES PROVIDER]... -# STRTAB_SECT OFFTAB_SECT EOFFTAB_SECT ARGTAB_SECT [PROBES_SECT PROVIDER_SECT]... -# -# Input globals: -# probes, base_probes, providers, probes_args, BCOUNT - -f_gen_dof_program() -{ - ###### Variables used to cache information needed later. - - # Number of section headers in the generated DOF program. - dof_secnum=0 - # Offset of section headers in the generated DOF program, in bytes. - dof_secoff=0 - - # Sizes of the STRTAB, OFFTAB and EOFFTAB sections, in bytes. - strtab_size=0 - offtab_size=0 - eofftab_size=0 - - # Offsets of the STRTAB, OFFTAB EOFFTAB and PROBES sections in the - # generated DOF program. In bytes. - strtab_offset=0 - offtab_offset=0 - eofftab_offset=0 - argtab_offset=0 - probes_offset=0 - - # Indexes of the section headers of the STRTAB, OFFTAB, EOFFTAB and - # PROBES sections in the sections array. - strtab_sect_index=0 - offtab_sect_index=0 - eofftab_sect_index=0 - argtab_sect_index=0 - probes_sect_index=0 - - # First offsets and eoffsets of the base-probes. - # Lines: PROVIDER(S) NAME(S) BASE(D) (DOF_OFFSET(D)|DOF_EOFFSET(D)) - probes_dof_offsets= - probes_dof_eoffsets= - - # Offsets in the STRTAB section for the first type of base probes. - # Record per line: PROVIDER(S) NAME(S) BASE(D) OFFSET(D) - probes_dof_types= - - - # Offsets of the provider names in the provider's STRTAB section. - # Lines: PROVIDER(S) OFFSET(D) - providers_dof_names= - - # Offsets of the base-probe names in the provider's STRTAB section. - # Lines: PROVIDER(S) NAME(S) BASE(D) OFFSET(D) - probes_dof_names= - - # Offsets of the provider sections in the DOF program. - # Lines: PROVIDER(S) OFFSET(D) - providers_offsets= - - ###### Generation phase. - - # The header of the DOF program contains a `struct - # dtrace_dof_hdr'. Record its size, but it is written at the end - # of the function. - f_incr_bcount $dof_hdrsize; f_align_bcount 8 - - # The STRTAB section immediately follows the header. It contains - # the following set of packed null-terminated strings: - # - # [PROVIDER [BASE_PROBE_NAME [BASE_PROBE_ARG_TYPE...]]...]... - strtab_offset=$BCOUNT - strtab_sect_index=$dof_secnum - dof_secnum=$((dof_secnum + 1)) - f_gen_asm "" - f_gen_asm "/* The STRTAB section. */" - f_gen_asm ".balign 8" - # Add the provider names. - off=0 - while read provider; do - strtab_size=$(($strtab_size + ${#prov} + 1)) - # Note the funny mangling... - f_gen_asm ".asciz \"$(printf %s $provider | $TR _ -)\"" - providers_dof_names=$(f_add_record "$providers_dof_names" \ - "$provider $off") - off=$(($off + ${#provider} + 1)) - - # Add the base-probe names. - while read p_provider name base base_sym; do - test "$p_provider" = "$provider" || continue - # And yes, more funny mangling... - f_gen_asm ".asciz \"$(printf %s $name | $TR _ -)\"" - probes_dof_names=$(f_add_record "$probes_dof_names" \ - "$p_provider $name $base $off") - off=$(($off + ${#name} + 1)) - while read args; do - a_provider=$(printf %s "$args" | $CUT -d: -f1) - a_name=$(printf %s "$args" | $CUT -d: -f2) - test "$a_provider" = "$p_provider" \ - && test "$a_name" = "$name" \ - || continue - - probes_dof_types=$(f_add_record "$probes_dof_types" \ - "$a_provider $name $base $off") - nargs=$(printf %s "$args" | $CUT -d: -f3) - for n in $($SEQ $nargs); do - arg=$(printf %s "$args" | $CUT -d: -f$(($n + 3))) - f_gen_asm ".asciz \"${arg}\"" - off=$(($off + ${#arg} + 1)) - done - done < /dev/null - break - fi - done < /dev/null) - test "$byte" = "$x86_op_jmp32" && nopret="$x86_op_ret" - - # Determine the patching sequence. It depends on the type of - # probe at hand (regular or is-enabled) and also if - # manipulating a 32bit or 64bit binary. - patchseq= - case $type in - p) patchseq=$(printf %s%s%s%s%s \ - "$nopret" \ - "$x86_op_nop" \ - "$x86_op_nop" \ - "$x86_op_nop" \ - "$x86_op_nop") - ;; - e) test "$objbits" -eq 64 && \ - patchseq=$(printf %s%s%s%s%s \ - "$x86_op_rex_rax" \ - "$x86_op_xor_eax_0" \ - "$x86_op_xor_eax_1" \ - "$nopret" \ - "$x86_op_nop") - test "$objbits" -eq 32 && \ - patchseq=$(printf %s%s%s%s%s \ - "$x86_op_xor_eax_0" \ - "$x86_op_xor_eax_1" \ - "$nopret" \ - "$x86_op_nop" \ - "$x86_op_nop") - ;; - *) f_panic "internal error: wrong probe type $type";; - esac - - # Patch! - printf %s "$patchseq" \ - | dd of=$objfile conv=notrunc count=5 ibs=1 bs=1 seek=$probe_off 2> /dev/null - done <\n" - printf "#include \n" - printf \\n\\n - - printf "#ifdef __cplusplus\nextern \"C\" {\n#endif\n" - - printf "#define _DTRACE_VERSION 1\n\n" - - provider=$(cat $dfile | $EGREP "^ *provider +([a-zA-Z_]+)" \ - | $SED -E -e 's/^ *provider +([a-zA-Z]+).*/\1/') - test -z "$provider" \ - && f_panic "unable to parse the provider name from $dfile." - u_provider=$(printf %s "$provider" | $TR a-z A-Z | $TR -s _) - - cat $dfile | $EGREP "^ *probe +[a-zA-Z_]+ *\(.*\);" | \ - while read line; do - # Extract the probe name. - name=$(printf %s "$line" \ - | $SED -E -e 's/^ *probe +([a-zA-Z_]+).*/\1/') - u_name=$(printf %s "$name" | $TR a-z A-Z | $TR -s _) - - # Generate an arg1,arg2,...,argN line for the probe. - args=""; nargs=0; aline=$(printf %s "$line" | $SED -e 's/.*(\(.*\)).*/\1/') - set -f; IFS=, - for arg in $aline; do - args="${args}arg${nargs}," - nargs=$((nargs + 1)) - done - set +f; unset IFS - args=${args%,} - - echo "#if _DTRACE_VERSION" - echo "" - - # Emit the macros for the probe. - echo "#define ${u_provider}_${u_name}($args) \\" - echo " __dtrace_${provider}___${name}($args)" - echo "#define ${u_provider}_${u_name}_ENABLED() \\" - echo " __dtraceenabled_${provider}___${name}()" - - # Emit the extern definitions for the probe dummy - # functions. - echo "" - printf %s\\n "$line" \ - | $SED -E -e "s/^ *probe +/extern void __dtrace_${provider}___/" - echo "extern int __dtraceenabled_${provider}___${name}(void);" - - - printf "\n#else\n" - - # Emit empty macros for the probe - echo "#define ${u_provider}_${u_name}($args)" - echo "#define ${u_provider}_${u_name}_ENABLED() (0)" - - printf "\n#endif /* _DTRACE_VERSION */\n" - done - - printf "#ifdef __cplusplus\n}\n#endif\n\n" - printf "#endif /* _${guard}_H */\n" -} - -### Main program. - -# Process command line arguments. - -test "$#" -eq "0" && f_usage - -genelf=0 -genheader=0 -objbits=64 -ofile= -dfile= -while getopts VG3264hs:o: name; do - case $name in - V) f_version;; - s) dfile="$OPTARG"; - test -f "$dfile" || f_panic "cannot read $dfile";; - o) ofile="$OPTARG";; - G) genelf=1;; - h) genheader=1;; - # Note the trick to support -32 - 3) objbits=666;; - 2) test "$objbits" -eq 666 || f_usage; objbits=32;; - # Likewise for -64 - 6) objbits=777;; - 4) test "$objbits" -eq 777 || f_usage; objbits=64;; - ?) f_usage;; - esac -done -shift $(($OPTIND - 1)) - -test "$objbits" -eq "32" || test "$objbits" -eq "64" \ - || f_usage - -test $((genelf + genheader)) -gt 1 && \ - { echo "Please use either -G or -h."; f_usage; } - -test -n "$dfile" || { echo "Please specify a .d file with -s."; exit 2; } - -if test "$genelf" -gt 0; then - # In this mode there must be a remaining argument: the name of the - # object file to inspect for probed points. - test "$#" -ne "1" && f_usage - test -f "$1" || f_panic "cannot read $1" - objfile=$1 - - # Collect probe information from the input object file and the - # d-script. - f_collect_probes $objfile - f_collect_probes_args $dfile - - # Generate the assembly code and assemble the DOF program in - # OFILE. Then patch OBJFILE to remove the dummy probe calls. - f_gen_dof_program - f_patch_objfile $objfile -fi - -if test "$genheader" -gt 0; then - test -n "$ofile" || { echo "Please specify an output file with -o."; exit 2; } - - # In this mode no extra arguments shall be present. - test "$#" -ne "0" && f_usage - - f_gen_header_file > $ofile -fi - -# pdtrace ends here. base-commit: 55b17f091c52b3c64d3e40e4df85790d14a683c6 -- 2.51.0