This is an archive of the discontinued LLVM Phabricator instance.

[llvm-nm] Print an explicit "no symbols" message when an object file has no symbols
ClosedPublic

Authored by rupprecht on Oct 2 2018, 4:26 PM.

Details

Summary

GNU nm (and other nm implementations, such as "go tool nm") prints an explicit "no symbols" message when an object file has no symbols. Currently llvm-nm just doesn't print anything. Adding an explicit "no symbols" message will allow llvm-nm to be used in place of nm: some scripts and build processes use nm <file> | grep "no symbols" as a test to see if a file has no symbols. It will also be more familiar to anyone used to nm.

That said, the format implemented here is slightly different, in that it doesn't print the tool name in the message (which IMHO is not useful to include).

Demo:

$ for nm in nm bin/llvm-nm ; do echo "nm implementation: $nm"; $nm /tmp/foo{1,2}.o; echo; done
nm implementation: nm

/tmp/foo1.o:
nm: /tmp/foo1.o: no symbols

/tmp/foo2.o:
0000000000000000 T foo2

nm implementation: bin/llvm-nm

/tmp/foo1.o:
no symbols

/tmp/foo2.o:
0000000000000000 T foo2

Diff Detail

Repository
rL LLVM

Event Timeline

rupprecht created this revision.Oct 2 2018, 4:26 PM
MaskRay accepted this revision.EditedOct 3 2018, 12:26 PM

Looks good, GNU and some BSD nm use: nm: /bin/cat: no symbols but the repeated command name and filename do not seem useful.

In POSIX.1-2017 specification of nm, "If no symbolic information is available for a valid input file, the nm utility shall report that fact, but not consider it an error condition."

This revision is now accepted and ready to land.Oct 3 2018, 12:26 PM

Looks good, GNU and some BSD nm use: nm: /bin/cat: no symbols but the repeated command name and filename do not seem useful.

In POSIX.1-2017 specification of nm, "If no symbolic information is available for a valid input file, the nm utility shall report that fact, but not consider it an error condition."

Thanks for that pointer!

This revision was automatically updated to reflect the committed changes.
sbc100 added a subscriber: sbc100.Jan 13 2020, 1:01 PM

I it seems that the printing of this error message only occurs with GNU nm if the object doesn't have a symbols table at all. Have no symbols in the table does not print the error message.

$ touch foo.c
$ gcc -c foo.c
$ nm foo.o  <- no error output here.
$ strip foo.o
$ nm foo.o
nm: foo.o: no symbols
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a subscriber: hiraditya. · View Herald Transcript

I it seems that the printing of this error message only occurs with GNU nm if the object doesn't have a symbols table at all. Have no symbols in the table does not print the error message.

$ touch foo.c
$ gcc -c foo.c
$ nm foo.o  <- no error output here.
$ strip foo.o
$ nm foo.o
nm: foo.o: no symbols

Interesting (subtle) behavior...

@rupprecht Do we know what projects parse "no symbols" from llvm-nm output?

I it seems that the printing of this error message only occurs with GNU nm if the object doesn't have a symbols table at all. Have no symbols in the table does not print the error message.

$ touch foo.c
$ gcc -c foo.c
$ nm foo.o  <- no error output here.
$ strip foo.o
$ nm foo.o
nm: foo.o: no symbols

Interesting (subtle) behavior...

@rupprecht Do we know what projects parse "no symbols" from llvm-nm output?

The one case I remember fixing was an integration test that ran something like strip <file>; nm <file> |& grep "no symbols" to make sure the strip step actually ran. So, the second case in the example above. There were a surprising number of other uses like this that I can't find anymore.

I think we should update it to not print "no symbols" if there is an empty symbol table, then. Nice find.

In emscripten we don't parse "no symbols" but we do run "llvm-nm -print-armap" and out users are seeing noise when they have objects with no symbols (not because they are stripped but simply because there are no public symbols).

https://github.com/emscripten-core/emscripten/pull/10198 is my workaround.

I've got a fix llvm-nm that I will upload, but funnily enough it doesn't actually solve the wasm issue. The reason is that with ELF we always generate at least one local symbols (the STT_FILE symbols) so no unstripped object will ever report "no symbols". However compiling the empty file on wasm does generate file with a symbol table of size zero.. which mean the fix I'm proposing doesn't actually fix our issue.

I've got a fix llvm-nm that I will upload, but funnily enough it doesn't actually solve the wasm issue. The reason is that with ELF we always generate at least one local symbols (the STT_FILE symbols) so no unstripped object will ever report "no symbols". However compiling the empty file on wasm does generate file with a symbol table of size zero.. which mean the fix I'm proposing doesn't actually fix our issue.

FWIW, if you create an ELF object from an assembly file, the STT_FILE symbol will only be created if you have a .file directive.

An ELF symbol table with only the null symbol at index 0 present does result in GNU nm producing "no symbols" for me, so it's not a missing/size 0 symbol table that is exactly important, just an effectively empty table.