Bug 29547 - binutils-2.39: fails to build against cctools nm (no '-B' option support)
Summary: binutils-2.39: fails to build against cctools nm (no '-B' option support)
Status: ASSIGNED
Alias: None
Product: binutils
Classification: Unclassified
Component: libctf (show other bugs)
Version: 2.39
: P2 normal
Target Milestone: ---
Assignee: Nick Alcock
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-09-04 22:36 UTC by Sergei Trofimovich
Modified: 2022-09-21 11:04 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2022-09-05 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2022-09-04 22:36:02 UTC
It's a forward of downstream https://github.com/NixOS/nixpkgs/pull/185297#issuecomment-1236398635 report by Robert Scott. There `binutils-2.39` (and I think `binutils-2.38`) fails to build against Darwin's `cctools` `nm` tool: https://gist.githubusercontent.com/risicle/dda04fc876a118f494e41a66d26f7eea/raw/2cc35e7f364c8dca6b5166b5140dcd8b1333cea9/gistfile1.txt

Relevant (I think) snpippet:

checking the name lister (/nix/store/2z3fkfy273yqg2ylxyybvly0dks1nlby-bootstrap-stage0-clang-wrapper-11.1.0/bin/nm -B) interface... yes

That `nm` is not from llvm, but from https://opensource.apple.com/source/cctools/, recent example: https://opensource.apple.com/source/cctools/cctools-973.0.1/misc/nm.c.auto.html

How it fails:

./libtool: eval: line 1115: syntax error near unexpected token `|'
./libtool: eval: line 1115: `/nix/store/2z3fkfy273yqg2ylxyybvly0dks1nlby-bootstrap-stage0-clang-wrapper-11.1.0/bin/nm -B  .libs/libctf_nobfd_la-ctf-archive.o .libs/libctf_nobfd_la-ctf-dump.o .libs/libctf_nobfd_la-ctf-create.o .libs/libctf_nobfd_la-ctf-decl.o .libs/libctf_nobfd_la-ctf-error.o .libs/libctf_nobfd_la-ctf-hash.o .libs/libctf_nobfd_la-ctf-labels.o .libs/libctf_nobfd_la-ctf-dedup.o .libs/libctf_nobfd_la-ctf-link.o .libs/libctf_nobfd_la-ctf-lookup.o .libs/libctf_nobfd_la-ctf-open.o .libs/libctf_nobfd_la-ctf-serialize.o .libs/libctf_nobfd_la-ctf-sha1.o .libs/libctf_nobfd_la-ctf-string.o .libs/libctf_nobfd_la-ctf-subr.o .libs/libctf_nobfd_la-ctf-types.o .libs/libctf_nobfd_la-ctf-util.o   |  | /nix/store/8ysd696cpacbvhy61z57w4vg7jn2gncz-bootstrap-stage0-clang/bin/sed 's/.* //' | sort | uniq > .libs/libctf-nobfd.exp'

Why it fails:

NM is detected as NM="nm -B" while this `nm` only supports `nm -p`:

$ nm -B a.o                             a.c
error: nm: invalid argument -B
Usage: nm [-agnopruUmxjlfAP[s segname sectname] [-] [-t format] [[-arch <arch_flag>] ...] [file ...]

$ nm -p a.o
0000000000000008 D _a
0000000000000000 T _b

$ nm a.o   
0000000000000008 D _a
0000000000000000 T _b

From what I understand `libtool.m4` marks the option as supported if `nm` stderr has `nm` output (ignoring the first line):

       # Check to see if the nm accepts a BSD-compat flag.
       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
       #   nm: unknown option "B" ignored
       case `"$tmp_nm" -B "$tmp_nm_to_nm" 2>&1 | grep -v '^ *$' | sed '1q'` in
       *$tmp_nm*) lt_cv_path_NM="$tmp_nm -B"
         break
         ;;
       *)
         case `"$tmp_nm" -p "$tmp_nm_to_nm" 2>&1 | grep -v '^ *$' | sed '1q'` in
         *$tmp_nm*)
           lt_cv_path_NM="$tmp_nm -p"
           break
           ;;
         *)
           lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
           continue # so that we can try to find one that supports BSD flags
           ;;
         esac
         ;;
       esac

It does not detect exit status or specific symbols printed from object file. Very unusual test.
Comment 1 Nick Alcock 2022-09-05 08:59:14 UTC
Adding an exit status test seems like a good idea, yes. I'll do that in the next few days (busy, but this is easy and machine time is cheap).

I don't have access to a Darwin machine and the compile farm obviously doesn't have any -- could you check that the result works once I have something?

(The reason for the oddness of this test is simply that we have to run nm on *something*, and many implementations forbid running it on /dev/null, and *correct* output on every implementation I have seen includes the file name. Of course, multi-line error messages might too... oops. I hope an exit status test will suffice to avoid that.)
Comment 2 Sergei Trofimovich 2022-09-05 17:07:14 UTC
(In reply to Nick Alcock from comment #1)
> Adding an exit status test seems like a good idea, yes. I'll do that in the
> next few days (busy, but this is easy and machine time is cheap).
> 
> I don't have access to a Darwin machine and the compile farm obviously
> doesn't have any -- could you check that the result works once I have
> something?

Yeah, I should be able to test possible fixes.

> (The reason for the oddness of this test is simply that we have to run nm on
> *something*, and many implementations forbid running it on /dev/null, and
> *correct* output on every implementation I have seen includes the file name.
> Of course, multi-line error messages might too... oops. I hope an exit
> status test will suffice to avoid that.)

Oh, would it also fail if nm happens to be a shell wrapper itself? I was about to wrap it for another unrelated reason.
Comment 3 Nick Alcock 2022-09-05 20:25:46 UTC
Having nm be a shell wrapper should be fine (I've been testing some of the odder edge cases that way). That's one reason we look through $PATH to find it ;)
Comment 4 Nick Alcock 2022-09-13 09:10:02 UTC
Oh this gets more fun. We can't use the exit code because some nm's return a nonzero exit code if no symbols are found! I'll have to add a grosser hack, looking for the string 'invalid argument' (in the C locale, naturally). This makes me feel rather ill :/

(It's starting to feel easier to compile something and then try to look for its symbols, but at this stage I don't think we are guaranteed a working compiler.)
Comment 5 Nick Alcock 2022-09-13 15:58:57 UTC
Something else! What if nm emits actual successful output? No nm out there is going to include its own name in the output in that case. We have to look for the expected format of the output (at least slightly) and consider the option accepted if that matches.

Anyway, I have something that might just work: try the users/nalcock/libtool-nm branch on binutils-gdb git. (It doesn't break x86 Linux, Solaris 2.11 or FreeBSD 13, which is all I've tested so far.)
Comment 6 Sergei Trofimovich 2022-09-14 08:08:09 UTC
(In reply to Nick Alcock from comment #5)
> Something else! What if nm emits actual successful output? No nm out there
> is going to include its own name in the output in that case. We have to look
> for the expected format of the output (at least slightly) and consider the
> option accepted if that matches.
> 
> Anyway, I have something that might just work: try the
> users/nalcock/libtool-nm branch on binutils-gdb git. (It doesn't break x86
> Linux, Solaris 2.11 or FreeBSD 13, which is all I've tested so far.)

Still fails in a similar way:

./libtool: eval: line 1115: syntax error near unexpected token `|'
./libtool: eval: line 1115: `/nix/store/kpc4vpii3zrnz53b87xvid0rxlqb66cc-cctools-binutils-darwin-949.0.1/bin/nm -B  .libs/libctf_la-ctf-archive.o .libs/libctf_la-ctf-dump.o .libs/libctf_la-ctf-create.o .libs/libctf_la-ctf-decl.o .libs/libctf_la-ctf-error.o .libs/libctf_la-ctf-hash.o .libs/libctf_la-ctf-labels.o .libs/libctf_la-ctf-dedup.o .libs/libctf_la-ctf-link.o .libs/libctf_la-ctf-lookup.o .libs/libctf_la-ctf-open.o .libs/libctf_la-ctf-serialize.o .libs/libctf_la-ctf-sha1.o .libs/libctf_la-ctf-string.o .libs/libctf_la-ctf-subr.o .libs/libctf_la-ctf-types.o .libs/libctf_la-ctf-util.o .libs/libctf_la-ctf-open-bfd.o   |  | /nix/store/69mrs7lcp77cln6d02gfw5hxiq3g8mkp-gnused-4.8/bin/sed 's/.* //' | sort | uniq > .libs/libctf.exp'
make[3]: *** [Makefile:687: libctf.la] Error 2

Trying to extract why it still fails to detect symbol extraction with the following patch:

--- a/libctf/configure
+++ b/libctf/configure
@@ -5972,6 +5972,14 @@ else
        # placating systems like Darwin and HP-UX, which mention the name of nm
        # in error output.
        #   nm: unknown option "B" ignored
+
+       echo "=============" >&2
+       "$tmp_nm" -B "$tmp_nm_to_nm" 2>&1
+       echo "=============" >&2
+       echo "=============" >&2
+       "$tmp_nm" -B "$tmp_nm_to_nm" 2>&1 | $GREP -v '^ *$' | $GREP -v 'nknown ' | $GREP -v 'nvalid ' | sed '1q'
+       echo "=============" >&2
+


checking for BSD- or MS-compatible name lister (nm)... =============
error: /nix/store/kpc4vpii3zrnz53b87xvid0rxlqb66cc-cctools-binutils-darwin-949.0.1/bin/nm: invalid argument -B
Usage: /nix/store/kpc4vpii3zrnz53b87xvid0rxlqb66cc-cctools-binutils-darwin-949.0.1/bin/nm [-agnopruUmxjlfAP[s segname sectname] [-] [-t format] [[-arch <arch_flag>] ...] [file ...]
=============
=============
Usage: /nix/store/kpc4vpii3zrnz53b87xvid0rxlqb66cc-cctools-binutils-darwin-949.0.1/bin/nm [-agnopruUmxjlfAP[s segname sectname] [-] [-t format] [[-arch <arch_flag>] ...] [file ...]
=============
/nix/store/kpc4vpii3zrnz53b87xvid0rxlqb66cc-cctools-binutils-darwin-949.0.1/bin/nm -B
Comment 7 Nick Alcock 2022-09-20 13:07:26 UTC
(Sorry for delay: post-conf collapse, UK bank holiday, massive change of
monitor configuration meaning my displays were scattered all around the
room for a day, etc)

On 14 Sep 2022, slyich at gmail dot com outgrape:

> checking for BSD- or MS-compatible name lister (nm)... =============
> error:
> /nix/store/kpc4vpii3zrnz53b87xvid0rxlqb66cc-cctools-binutils-darwin-949.0.1/bin/nm:
> invalid argument -B
> Usage:
> /nix/store/kpc4vpii3zrnz53b87xvid0rxlqb66cc-cctools-binutils-darwin-949.0.1/bin/nm
> [-agnopruUmxjlfAP[s segname sectname] [-] [-t format] [[-arch <arch_flag>] ...]
> [file ...]
> =============

Oh, multiple lines ending with a usage message, and with the last line
citing the name of the running binary? OK, we can trigger on 'Usage: '
then. (Ew. Still, most unlikely to be a word that appears on the last
line of a legitimate run. This function *really* needs a proper rewrite...)

Try the branch now? (Tested locally as before, plus on mingw.)
Comment 8 Sergei Trofimovich 2022-09-20 22:45:43 UTC
(In reply to Nick Alcock from comment #7)
> (Sorry for delay: post-conf collapse, UK bank holiday, massive change of
> monitor configuration meaning my displays were scattered all around the
> room for a day, etc)
> 
> On 14 Sep 2022, slyich at gmail dot com outgrape:
> 
> > checking for BSD- or MS-compatible name lister (nm)... =============
> > error:
> > /nix/store/kpc4vpii3zrnz53b87xvid0rxlqb66cc-cctools-binutils-darwin-949.0.1/bin/nm:
> > invalid argument -B
> > Usage:
> > /nix/store/kpc4vpii3zrnz53b87xvid0rxlqb66cc-cctools-binutils-darwin-949.0.1/bin/nm
> > [-agnopruUmxjlfAP[s segname sectname] [-] [-t format] [[-arch <arch_flag>] ...]
> > [file ...]
> > =============
> 
> Oh, multiple lines ending with a usage message, and with the last line
> citing the name of the running binary? OK, we can trigger on 'Usage: '
> then. (Ew. Still, most unlikely to be a word that appears on the last
> line of a legitimate run. This function *really* needs a proper rewrite...)
> 
> Try the branch now? (Tested locally as before, plus on mingw.)

Tried against commit f71e2751ed8db0f041f9e46487 "fixup! libtool.m4: adjust kludge for ignoring syntax errors".

Seems to build binutils just fine! Detected `nm -p` command option.
Comment 9 Nick Alcock 2022-09-21 11:03:45 UTC
On 20 Sep 2022, slyich at gmail dot com spake thusly:
> Seems to build binutils just fine! Detected `nm -p` command option.

Great! It'll go in the next tranche, and probably be backported to 2.39.
(But that's a week or so off -- long test runs plus a bunch of other
stuff I want to get in at the same time, courtesy of feature requests at
LPC. :) )