This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Print symbols with non-default versions for better "undefined symbol" diagnostics
ClosedPublic

Authored by MaskRay on Mar 28 2020, 4:13 PM.

Details

Summary

When reporting an "undefined symbol" diagnostic:

This can lead to confusing diagnostics:

// foo may be foo@v2
ld.lld: error: undefined symbol: foo
>>> referenced by t1.o:(.text+0x1)
// foo may be foo@v1 or foo@@v1
>>> did you mean: foo
>>> defined in: t.so

There are 2 ways a symbol in symtab may get truncated:

  • A @@ definition may be truncated *early* by SymbolTable::insert(). The name ends with a '\0'.
  • A @ definition/reference may be truncated *later* by Symbol::parseSymbolVersion(). The name ends with a '@'.

This patch detects the second case and improves the diagnostics. The first case is not improved but the second case is sufficient to make diagnostics not confusing.

Diff Detail

Event Timeline

MaskRay created this revision.Mar 28 2020, 4:13 PM
grimar added inline comments.Mar 30 2020, 4:00 AM
lld/ELF/Relocations.cpp
903 ↗(On Diff #253384)

This is OK I think. Though I wonder if it would be cleaner to add a method to Symbol like:

StringRef getFullName() const { return {nameData}; }

And just use it?

lld/test/ELF/undef-suggest-version.s
17

Probably would be reasonable to add a test for @@ case too?

MaskRay updated this revision to Diff 253652.Mar 30 2020, 11:50 AM
MaskRay marked an inline comment as done.
MaskRay retitled this revision from [ELF] Suggest VERSYM_HIDDEN shared definitions to [ELF] Print versioned name for better "undefined symbol" diagnostics.
MaskRay edited the summary of this revision. (Show Details)

Fix more problems

MaskRay marked an inline comment as done.Mar 30 2020, 11:51 AM
MaskRay added inline comments.
lld/ELF/Relocations.cpp
903 ↗(On Diff #253384)

We need to demangle the unversioned part, then append @.

The demangler cannot process @. I changed lld::toString instead.

grimar added inline comments.Mar 31 2020, 4:15 AM
lld/ELF/Symbols.cpp
41

Though it is technically looks correct at this moment, it looks a bit hacky still. It violates the contract StringRef provides:
it is unexpected that user will access the buffer outside of its Size.

Is it a time to make toString method a member of Symbol? Since it is a global function that now relies on the assumption about internal implementation. (With that you will be able to access nameData member directly, what should be cleaner).

I also wonder what other people think. May be it just me who think it is a bit too hacky :)

46

Missing an empty line before this one.

lld/ELF/Symbols.h
24

"Print"? Perhaps "Returns" as it does not actually pring anything to an output.

lld/test/ELF/undef-suggest-version.s
7

I'd rephrase. It probably reads like we expect to see "did you mean: bar@@v1` in the error message?
Perhaps: "Check we suggest the symbol with a default version..."

39

MIssing a comment.

MaskRay updated this revision to Diff 253911.Mar 31 2020, 9:09 AM

Improve test comments

ruiu added inline comments.Mar 31 2020, 9:57 PM
lld/ELF/Symbols.h
24

I don't think you need to put emphasis on "versioned". You can just say that this function returns a string representation for a symbol used for error reporting.

MaskRay updated this revision to Diff 254092.Mar 31 2020, 10:07 PM
MaskRay marked 5 inline comments as done.

Address comments

ruiu accepted this revision.Mar 31 2020, 10:39 PM

LGTM

This revision is now accepted and ready to land.Mar 31 2020, 10:39 PM
grimar added inline comments.Apr 1 2020, 2:02 AM
lld/ELF/Symbols.cpp
41

This my concern perhaps should not be a stopper for this patch, since you have LGTM.

MaskRay updated this revision to Diff 254205.Apr 1 2020, 8:02 AM
MaskRay retitled this revision from [ELF] Print versioned name for better "undefined symbol" diagnostics to [ELF] Print symbols with non-default versions for better "undefined symbol" diagnostics.
MaskRay edited the summary of this revision. (Show Details)

Clarify that we only improve diagnostics for non-default versions.

MaskRay edited the summary of this revision. (Show Details)Apr 1 2020, 8:04 AM
MaskRay marked an inline comment as done.Apr 1 2020, 8:07 AM
MaskRay added inline comments.
lld/ELF/Symbols.cpp
41

I have thought about the problem, but it is difficult to improve the situation.
nameSize is truncated here:

void Symbol::parseSymbolVersion() {
  StringRef s = getName();
  size_t pos = s.find('@');
  if (pos == 0 || pos == StringRef::npos)
    return;
  StringRef verstr = s.substr(pos + 1);
  if (verstr.empty())
    return;

  // Truncate the symbol name so that it doesn't include the version string.
  nameSize = pos;
This revision was automatically updated to reflect the committed changes.