git: 5c7b986c21ed - main - lorder: Clean up and improve robustness.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Feb 2024 15:44:33 UTC
The branch main has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=5c7b986c21ed47545203e8f630fe2281b83112d2
commit 5c7b986c21ed47545203e8f630fe2281b83112d2
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2024-02-28 15:37:36 +0000
Commit: Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2024-02-28 15:37:36 +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
---
usr.bin/lorder/lorder.1 | 22 ++++++------
usr.bin/lorder/lorder.sh | 92 ++++++++++++++++++++++++++++++------------------
2 files changed, 69 insertions(+), 45 deletions(-)
diff --git a/usr.bin/lorder/lorder.1 b/usr.bin/lorder/lorder.1
index b71756b03b49..4c70cd2f4729 100644
--- a/usr.bin/lorder/lorder.1
+++ b/usr.bin/lorder/lorder.1
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd March 21, 2023
+.Dd February 27, 2024
.Dt LORDER 1
.Os
.Sh NAME
@@ -44,13 +44,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
@@ -58,11 +55,11 @@ 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
@@ -97,3 +94,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 a24f844e5790..be28eec8b9bc 100644
--- a/usr.bin/lorder/lorder.sh
+++ b/usr.bin/lorder/lorder.sh
@@ -29,35 +29,50 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-# 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
@@ -68,21 +83,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