From nobody Thu Apr 04 11:39:06 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4V9KQM2pHgz5GrS7; Thu, 4 Apr 2024 11:39:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (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 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4V9KQM0gyzz57rx; Thu, 4 Apr 2024 11:39:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1712230747; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=/TR6izutHBXhgHTDXsSl6WCAQIp/kWeRNyq3No5haSI=; b=ERHjwZJTlUq8kkUtqfCjapRe30reQGbRQWvnwN5vD9EGBLOkkxw6cTo1sBWzcOTvb7U/X6 mdYxLbbUgTW0xJLwHAk4/K6n/9ri2P2XmyY29y9L3ClXzdbx1jgaW9lFDkwQf6+zswgsCX FIpgNrySfHY08owe1zF6hifhK1ozisjMcT5y/pS8pN0JtWGesMd37q8bfZtheE/cjq4WZz Vrm9snuTaDy9zjW/JgKV1VtbiM+C2jfKJHk9RbeyaU0kK2g6rdI7dvtylbtnh0JXbxBlvg 09JqL6z3odDpxX9IfhM6wC7XDIcYPAFoNM7Nt9X+i5Lb+WdMAm2qrktKlR5DTQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1712230747; a=rsa-sha256; cv=none; b=OPuTyNve5346e0pjnkTanMdPZpS/EZjG7baY3tAfBdtzVgvI/xRr+o6yvzPZjvbrOYlsjk tm5lJWIr54DyjJRp2Itnp9FAe4Ez9uLqGDaDtT0GUhHaqWETnlJf+8U1MjbQJSmAV+dOMF 0iPjWH2DP0thOyVKrmunwF41jRHdzlMbJATSF7RoLSrwh1XJ6TNZ9poBy+8mp9Wu+1CHu9 NqTuP12DuX5RnVbz3Gq5GEE3sPJltJ60hoVoiyncF0n6LabIh8r8hc1KBozW/Jr7DooiCC zdeMtE/fz5sGY2rPTnTXOUsImlpHX+FE+GPR4anwF72sSl/LNMBbtbSNXfClFA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1712230747; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=/TR6izutHBXhgHTDXsSl6WCAQIp/kWeRNyq3No5haSI=; b=Hevo1yD8DzKXWfWjmyZNilhquqwo5rTCCcclkNzrGS5lPgiDm7jZO5+mPUizAPEtmXBqT2 Q8vcPtjAKDUeZPTp8Pqpx/zcnggNcvOG5xBjtnDmhw0vsxekmW8WayPOl5QRuJeLt/DRui x65kmjkfUyFtdDtQFjqv6l41+l9xfizUPb8cmWuz8oqPYwfn0/S6KR1wnclGaTDPGHseyt 93MEr9ttuvgndw5VYtmwtNsjUu5B8LOkBNoDhZZCH61zcGT3LfTJDZ19ZoRiwsG5nb3CYz 5Ub4AAg94wLItBZfUhMFqQJQ8/hMHkAb0frCLsxslF7QEOXe+hfUTx1BbeFg0w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4V9KQM02cpzFJN; Thu, 4 Apr 2024 11:39:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 434Bd6If060295; Thu, 4 Apr 2024 11:39:06 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 434Bd6jp060292; Thu, 4 Apr 2024 11:39:06 GMT (envelope-from git) Date: Thu, 4 Apr 2024 11:39:06 GMT Message-Id: <202404041139.434Bd6jp060292@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 6895133fe293 - stable/13 - lorder: Clean up and improve robustness. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 6895133fe293902f19a060c0cf229ea9b23bb555 Auto-Submitted: auto-generated The branch stable/13 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=6895133fe293902f19a060c0cf229ea9b23bb555 commit 6895133fe293902f19a060c0cf229ea9b23bb555 Author: Dag-Erling Smørgrav AuthorDate: 2024-02-28 15:37:36 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2024-04-04 09:55:25 +0000 lorder: Clean up and improve robustness. * Properly parse (no) command-line options. * Ensure that errors go to stderr and result in a non-zero exit. * Drop the special-case code for a single argument, as it will produce the wrong outcome if the file does not exist or is corrupted. * Don't print anything until after we've collected all the data. * Always create all temporary files before setting the trap. This ensures that the trap can safely fire at any moment, regardless of any previous definition of `T`. * Use a temporary file rather than a pipe between `nm` and `sed` to ensure proper termination if `nm` fails due to a missing or invalid input. * The check for self-referential entries was conditional on testing our argument list against a regex looking for archives. This was a needless and unreliable optimization; make the check unconditional. * Document that lorder will not work properly if any of its inputs have spaces in their name. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: allanjude Differential Revision: https://reviews.freebsd.org/D44133 (cherry picked from commit 5c7b986c21ed47545203e8f630fe2281b83112d2) lorder: Add unit tests. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: allanjude Differential Revision: https://reviews.freebsd.org/D44134 (cherry picked from commit 96da41b6dbf383436018f11ad8a672faab2d3789) lorder: Undeprecate. While lorder is not required by our current toolchain (or any toolchain we've used in the past decade or two), it still occasionally shows up in build systems of third party software, including The Open Group's UNIX conformance test suite, and the maintenance cost is negligible. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: imp, allanjude, emaste Differential Revision: https://reviews.freebsd.org/D44135 (cherry picked from commit cf4d9bf8b38819da12c6d686d5cf6dbd6353cd61) lorder: Don't rely on legacy syntax. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: allanjude Differential Revision: https://reviews.freebsd.org/D44155 (cherry picked from commit aedb37dc49319a7cd1faf34f312a8a9fc01e611d) lorder: Tweak invalid file test. Different implementations of `nm` have different ways of telling you that your file is not a valid object or library, but they all seem to have “not recognized” as a common substring. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: allanjude Differential Revision: https://reviews.freebsd.org/D44154 (cherry picked from commit aa80cfadff0bb715ca090cbd1b3561a1619251d5) usr.bin: Make lorder conditional on MK_TOOLCHAIN. MFC after: 1 week Reviewed by: allanjude, markj Differential Revision: https://reviews.freebsd.org/D44558 (cherry picked from commit 125c4560bc70971b950d035cfcd2255b89984011) --- etc/mtree/BSD.tests.dist | 2 + tools/build/mk/OptionalObsoleteFiles.inc | 6 ++ usr.bin/Makefile | 2 +- usr.bin/lorder/Makefile | 5 ++ usr.bin/lorder/lorder.1 | 37 +++++------ usr.bin/lorder/lorder.sh | 94 ++++++++++++++++---------- usr.bin/lorder/tests/Makefile | 4 ++ usr.bin/lorder/tests/lorder_test.sh | 111 +++++++++++++++++++++++++++++++ 8 files changed, 203 insertions(+), 58 deletions(-) diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index 7c9b2464724c..82c77c6d43c7 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -1061,6 +1061,8 @@ .. lockf .. + lorder + .. m4 .. mkimg diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 4b78c655f73c..e068ad8b5f91 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -8982,6 +8982,12 @@ OLD_FILES+=usr/share/man/man3/elftc_set_timestamps.3.gz OLD_FILES+=usr/share/man/man3/elftc_timestamp.3.gz OLD_FILES+=usr/share/man/man3/elftc_string_table_create.3.gz OLD_FILES+=usr/share/man/man3/elftc_version.3.gz +# usr.bin/lorder +OLD_FILES+=usr/bin/lorder +OLD_FILES+=usr/tests/usr.bin/lorder/Kyuafile +OLD_FILES+=usr/tests/usr.bin/lorder/lorder_test +OLD_DIRS+=usr/tests/usr.bin/lorder +# usr.bin/yacc OLD_FILES+=usr/tests/usr.bin/yacc/Kyuafile OLD_FILES+=usr/tests/usr.bin/yacc/btyacc_calc1.y OLD_FILES+=usr/tests/usr.bin/yacc/btyacc_demo.y diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 54b45dca0e24..f3150691003c 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -82,7 +82,6 @@ SUBDIR= alias \ logins \ logname \ look \ - lorder \ lsvfs \ lzmainfo \ m4 \ @@ -275,6 +274,7 @@ SUBDIR.${MK_TOOLCHAIN}+= file2c SUBDIR.${MK_TOOLCHAIN}+= gprof SUBDIR.${MK_TOOLCHAIN}+= indent SUBDIR.${MK_TOOLCHAIN}+= lex +SUBDIR.${MK_TOOLCHAIN}+= lorder SUBDIR.${MK_TOOLCHAIN}+= mkstr SUBDIR.${MK_TOOLCHAIN}+= rpcgen SUBDIR.${MK_TOOLCHAIN}+= unifdef diff --git a/usr.bin/lorder/Makefile b/usr.bin/lorder/Makefile index a94860b51c6a..112dd5df2a1e 100644 --- a/usr.bin/lorder/Makefile +++ b/usr.bin/lorder/Makefile @@ -1,6 +1,11 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 +.include + SCRIPTS=lorder.sh MAN= lorder.1 +HAS_TESTS= +SUBDIR.${MK_TESTS}= tests + .include diff --git a/usr.bin/lorder/lorder.1 b/usr.bin/lorder/lorder.1 index e268f81d7254..478b7f493e03 100644 --- a/usr.bin/lorder/lorder.1 +++ b/usr.bin/lorder/lorder.1 @@ -27,17 +27,12 @@ .\" .\" @(#)lorder.1 8.2 (Berkeley) 4/28/95 .\" -.Dd March 21, 2023 +.Dd February 27, 2024 .Dt LORDER 1 .Os .Sh NAME .Nm lorder .Nd list dependencies for object files -.Sh DEPRECATION NOTICE -.Nm -is obsolete and may not be present in -.Fx 14 -and later. .Sh SYNOPSIS .Nm .Ar @@ -46,13 +41,10 @@ The .Nm utility uses .Xr nm 1 -to determine interdependencies in the list of object files -and library archives -specified on the command line. -The -.Nm -utility outputs a list of file names where the first file contains a symbol -which is defined by the second file. +to determine interdependencies between object files and library +archives listed on its command line. +It then outputs a list of pairs of file names such that the first file +in each pair references at least one symbol defined by the second. .Pp The output is normally used with .Xr tsort 1 @@ -60,18 +52,16 @@ when a library is created to determine the optimum ordering of the object modules so that all references may be resolved in a single pass of the loader. .Pp -When linking static binaries, +Similarly, when linking static binaries, .Nm and .Xr tsort 1 -can be used to properly order library archives automatically. +can be used to sort libraries in order of dependency. .Pp -The use of -.Nm -is not required by contemporary linkers, and -.Nm -may be removed from a future version of -.Fx . +While contemporary linkers no longer require the use of +.Nm , +it is provided for the benefit of legacy code bases and build +systems which still insist on it. .Sh ENVIRONMENT .Bl -tag -width indent .It Ev NM @@ -99,3 +89,8 @@ A .Nm utility appeared in .At v7 . +.Sh CAVEATS +The +.Nm +utility will not work properly if given file names with spaces or +newlines in them. diff --git a/usr.bin/lorder/lorder.sh b/usr.bin/lorder/lorder.sh index 640e128b0cb9..c0a7dbbd43e6 100644 --- a/usr.bin/lorder/lorder.sh +++ b/usr.bin/lorder/lorder.sh @@ -33,35 +33,50 @@ # # -# only one argument is a special case, just output the name twice -case $# in - 0) - echo "usage: lorder file ..."; - exit ;; - 1) - echo $1 $1; - exit ;; -esac +export LC_CTYPE=C +export LC_COLLATE=C +set -e -# temporary files +usage() { + echo "usage: lorder file ..." >&2 + exit 1 +} + +while getopts "" opt ; do + case $opt in + *) + usage + ;; + esac +done +shift $(($OPTIND - 1)) +if [ $# -eq 0 ] ; then + usage +fi + +# +# Create temporary files. +# +N=$(mktemp -t _nm_) R=$(mktemp -t _reference_) S=$(mktemp -t _symbol_) +T=$(mktemp -t _temp_) NM=${NM:-nm} -# remove temporary files on HUP, INT, QUIT, PIPE, TERM -trap "rm -f $R $S $T; exit 1" 1 2 3 13 15 - -# make sure all the files get into the output -for i in $*; do - echo $i $i -done +# +# Remove temporary files on termination. +# +trap "rm -f $N $R $S $T" EXIT 1 2 3 13 15 -# if the line has " [RTDW] " it's a globally defined symbol, put it -# into the symbol file. # -# if the line has " U " it's a globally undefined symbol, put it into -# the reference file. -${NM} ${NMFLAGS} -go $* | sed " +# A line matching " [RTDW] " indicates that the input defines a symbol +# with external linkage; put it in the symbol file. +# +# A line matching " U " indicates that the input references an +# undefined symbol; put it in the reference file. +# +${NM} ${NMFLAGS} -go "$@" >$N +sed -e " / [RTDW] / { s/:.* [RTDW] / / w $S @@ -72,21 +87,28 @@ ${NM} ${NMFLAGS} -go $* | sed " w $R } d -" +" <$N -export LC_ALL=C -# eliminate references that can be resolved by the same library. -if [ $(expr "$*" : '.*\.a[[:>:]]') -ne 0 ]; then - sort -u -o $S $S - sort -u -o $R $R - T=$(mktemp -t _temp_) - comm -23 $R $S >$T - mv $T $R -fi +# +# Elide entries representing a reference to a symbol from within the +# library that defines it. +# +sort -u -o $S $S +sort -u -o $R $R +comm -23 $R $S >$T +mv $T $R + +# +# Make sure that all inputs get into the output. +# +for i ; do + echo "$i" "$i" +done -# sort references and symbols on the second field (the symbol), -# join on that field, and print out the file names. +# +# Sort references and symbols on the second field (the symbol), join +# on that field, and print out the file names. +# sort -k 2 -o $R $R sort -k 2 -o $S $S -join -j 2 -o 1.1 2.1 $R $S -rm -f $R $S +join -j 2 -o 1.1 -o 2.1 $R $S diff --git a/usr.bin/lorder/tests/Makefile b/usr.bin/lorder/tests/Makefile new file mode 100644 index 000000000000..21207f413a8d --- /dev/null +++ b/usr.bin/lorder/tests/Makefile @@ -0,0 +1,4 @@ +PACKAGE= tests +ATF_TESTS_SH= lorder_test + +.include diff --git a/usr.bin/lorder/tests/lorder_test.sh b/usr.bin/lorder/tests/lorder_test.sh new file mode 100644 index 000000000000..a4276b2dcfe6 --- /dev/null +++ b/usr.bin/lorder/tests/lorder_test.sh @@ -0,0 +1,111 @@ +# +# Copyright (c) 2024 Klara, Inc. +# +# SPDX-License-Identifier: BSD-2-Clause +# + +atf_test_case noargs +noargs_head() { + atf_set descr "No arguments" +} +noargs_body() { + atf_check -s exit:1 -e match:"^usage:" \ + lorder +} + +atf_test_case onearg +onearg_head() { + atf_set descr "One argument" +} +onearg_body() { + echo "void a(void) { }" >a.c + cc -o a.o -c a.c + echo "a.o a.o" >output + atf_check -o file:output \ + lorder *.o +} + +atf_test_case dashdash +dashdash_head() { + atf_set descr "One argument" +} +dashdash_body() { + echo "void a(void) { }" >a.c + cc -o a.o -c a.c + echo "a.o a.o" >output + atf_check -o file:output \ + lorder -- *.o +} + +atf_test_case nonexistent +nonexistent_head() { + atf_set descr "Nonexistent file" +} +nonexistent_body() { + atf_check -s not-exit:0 -e match:"No such file" -o empty \ + lorder nonexistent.o +} + +atf_test_case invalid +invalid_head() { + atf_set descr "Invalid file" +} +invalid_body() { + echo "not an object file" >invalid.o + atf_check -s not-exit:0 -e match:"not recognized" -o empty \ + lorder invalid.o +} + +atf_test_case objects +objects_head() { + atf_set descr "Order objects" +} +objects_body() { + echo "void a(void) { }" >a.c + echo "void a(void); void b(void) { a(); }" >b.c + echo "void b(void); void c(void) { b(); }" >c.c + for n in a b c ; do + cc -o $n.o -c $n.c + echo "$n.o $n.o" + done >output + echo "b.o a.o" >>output + echo "c.o b.o" >>output + atf_check -o file:output \ + lorder *.o +} + +atf_test_case archives +archives_head() { + atf_set descr "Order archives" +} +archives_body() { + echo "void a(void) { }" >a.c + echo "void a(void); void b(void) { a(); }" >b.c + echo "void b(void); void c(void) { b(); }" >c.c + echo "void e(void); void d(void) { e(); }" >d.c + echo "void d(void); void e(void) { d(); }" >e.c + for n in a b c d e ; do + cc -o $n.o -c $n.c + done + for n in a b c ; do + ar -crs $n.a $n.o + echo "$n.a $n.a" + done >output + ar -crs z.a d.o e.o + echo "z.a z.a" >>output + echo "b.a a.a" >>output + echo "c.a b.a" >>output + atf_check -o file:output \ + lorder *.a +} + +atf_init_test_cases() +{ + atf_add_test_case noargs + atf_add_test_case onearg + atf_add_test_case dashdash + atf_add_test_case nonexistent + atf_add_test_case invalid + atf_add_test_case objects + atf_add_test_case archives +}