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