This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Don't warn on undefined symbols if UnresolvedPolicy::Ignore is used
ClosedPublic

Authored by MaskRay on Oct 9 2018, 2:55 PM.

Details

Summary

Add a condition UnresolvedPolicy::Ignore to elf::warnUnorderedSymbol to suppress Sym->isUndefined() warnings from both

  1. --symbol-ordering-file=
  2. .llvm.call-graph-profile

If --unresolved-symbols=ignore-all is used,

no "undefined symbol" error/warning is emitted. It makes sense to not warn unorderable symbols.

Otherwise,

If an executable is linked, the default policy UnresolvedPolicy::ErrorOrWarn will issue a "undefined symbol" error. The unorderable symbol warning is redundant.

If a shared object is linked, it is possible that only part of object files are used and some symbols are left undefined. The warning is not very necessary.
  In particular for .llvm.call-graph-profile, when linking a shared object, a call graph profile may contain undefined symbols. This case generated a warning before but it will be suppressed by this patch.

Event Timeline

MaskRay created this revision.Oct 9 2018, 2:55 PM
ruiu added a comment.Oct 9 2018, 3:03 PM

You should skip an undefined symbol if it is created from a DSO, no? Looks like just skipping all undefined symbols there also suppresses legitimate warnings.

MaskRay updated this revision to Diff 168880.Oct 9 2018, 3:06 PM

Use UnresolvedPolicy::Ignore

ruiu added a comment.Oct 9 2018, 3:13 PM

Does that make sense? I still feel like ignoring undefined symbols spoils the point of calling that function in the first place.

What is the intended use of such warnings?

Does that make sense? I still feel like ignoring undefined symbols spoils the point of calling that function in the first place.

Do you think that when linking a shared object, users should specify --no-warn-symbol-ordering to suppress the unable to order undefined symbol: warning?

elf::warnUnorderableSymbol(const Symbol *Sym) is used in 1) reading call graph profile sections 2) --symbol-ordering-file=

FWIW, ld.bfd just ignores undefined symbols with --symbol-ordering-file=. I don't like that behavior and I think lld is right to give some warnings as it currently does. But regarding call graph profile, when linking a shared object with some undefined symbols, I feel the UnresolvedPolicy::Ignore mechanism (--shared implies Ignore) can be reused to suppress such warnings.

ruiu added a comment.Oct 9 2018, 3:26 PM

I don't think I understand the point of this patch. You can't reorder undefined symbols, so why does CG-profile section contains undefined symbol in the first place?

I don't think I understand the point of this patch. You can't reorder undefined symbols, so why does CG-profile section contains undefined symbol in the first place?

My understanding is that if you link an executable, all .cg_profile symbols should be defined. However, with -shared, it is possible that only partial object files are linked and some symbols are left undefined. By separating From and To symbols into different modules, the .cg_profile From, To, count directives are essentially rendered useless, but I feel this is intended and no warnings should be given.

ruiu added a comment.Oct 9 2018, 3:39 PM

It needs to be explained. I couldn't get it just by reading two lines of code.

MaskRay updated this revision to Diff 168895.Oct 9 2018, 4:01 PM

Add comment why we use

if (!Sym->isUndefined() ||
    Config->UnresolvedSymbols != UnresolvedPolicy::Ignore)
grimar added a subscriber: grimar.Oct 10 2018, 1:08 AM
grimar added inline comments.
ELF/Driver.cpp
689 ↗(On Diff #168895)

It reads strangely: "If a symbol is not undefined (or ...) then warnUnorderableSymbol"
Makes think that we reporting a warning for defined symbols.

I think if that check should be made it should be inside the warnUnorderableSymbol

Also, should it check the if (Config->Shared) condition at some point?

MaskRay added inline comments.Oct 10 2018, 10:15 AM
ELF/Driver.cpp
689 ↗(On Diff #168895)

I think if that check should be made it should be inside the warnUnorderableSymbol

Then this option will also affect --symbol-ordering-file= (ld.bfd implements this option but gold doesn't. ld.bfd does not warn undefined symbols.). I think this also seems fine.

Config->Shared

Checking UnresolvedPolicy::Ignore looks good enough as this is also a symbol resolution process.

MaskRay updated this revision to Diff 169061.Oct 10 2018, 11:29 AM

Lower UnresolvedPolicy check to warnUnorderableSymbol

MaskRay updated this revision to Diff 169067.Oct 10 2018, 11:59 AM
MaskRay retitled this revision from [ELF] Don't warn on undefined symbols when reading call graph profile to [ELF] Don't warn on undefined symbols if UnresolvedPolicy::Ignore is used.
MaskRay edited the summary of this revision. (Show Details)
MaskRay removed a subscriber: grimar.

.

MaskRay marked 2 inline comments as done.Oct 10 2018, 12:01 PM
MaskRay added a comment.EditedOct 10 2018, 12:11 PM

After thinking it over, I decide to sink the UnresolvedPolicy::Ignore condition to elf::warnUnorderedSymbol to suppress Sym->isUndefined() warnings from both 1) --symbol-ordering-file= and 2) .llvm.call-graph-profile

The test symbol-ordering-file-warnings.s uses --unresolved-symbols=ignore-all to check warnings of Sym->isUndefined(). But I think it makes more sense to just don't warn the unorderable symbol case, as the error: undefined symbol: $symbol error/warning is also suppressed. If the symbol does not exist, users will still see warning: symbol ordering file: no such symbol: $symbol. This change does not make the status worse.

MaskRay updated this revision to Diff 169072.Oct 10 2018, 12:26 PM
MaskRay edited the summary of this revision. (Show Details)

Reword the comment

ruiu added inline comments.Oct 10 2018, 1:54 PM
ELF/Symbols.cpp
283–290

Please do not change this -- this code was written in the way it is to reduce indentation depth.

MaskRay added inline comments.Oct 10 2018, 3:06 PM
ELF/Symbols.cpp
283–290

Should I use if (Sym->isUndefined() && Config->UnresolvedSymbols != UnresolvedPolicy::Ignore) then?

I actually find dispatching by SymbolKind first makes the code a bit easier to understand:

  • Undefined
  • Shared
  • Others (Defined)

For the Defined case, fine-grained conditions are checked for absolute/syunthetic/discarded.

I lean to this style but if you have strong opinion on this, I can change it.

ruiu added inline comments.Oct 10 2018, 3:10 PM
ELF/Symbols.cpp
283–290

Yeah, maybe you should write that if at the beginning of this function to exit early.

MaskRay added inline comments.Oct 10 2018, 3:22 PM
ELF/Symbols.cpp
283–290

But that way:

  if (Sym->isUndefined() && Config->UnresolvedSymbols != UnresolvedPolicy::Ignore)
    Warn(": unable to order undefined symbol: ");
  else if (Sym->isShared())
    Warn(": unable to order undefined symbol: ");
  else if (Sym->isShared())
    Warn(": unable to order shared symbol: ");
////// Sym->isUndefined() is possible here
  else if (D && !D->Section)
    Warn(": unable to order absolute symbol: ");
  else if (D && isa<OutputSection>(D->Section))
    Warn(": unable to order synthetic symbol: ");
  else if (D && !D->Section->Repl->Live)
    Warn(": unable to order discarded symbol: ");

Will that cause a problem?

MaskRay added inline comments.Oct 10 2018, 3:27 PM
ELF/Symbols.cpp
283–290

Sorry I misread your words. I think you mean:

void elf::warnUnorderableSymbol(const Symbol *Sym) {
  if (!Config->WarnSymbolOrdering ||
      Config->UnresolvedSymbols == UnresolvedPolicy::Ignore)
    return;

But this way UnresolvedPolicy::Ignore also changes how Shared Defined symbols are interpreted. UnresolvedPolicy::Ignore is also used otherwhere, but only related to how undefined symbols are interpreted.

ruiu added inline comments.Oct 10 2018, 3:31 PM
ELF/Symbols.cpp
283–290

I mean you can exit early if Sym->isUndefined() && Config->UnresolvedSymbols != UnresolvedPolicy::Ignore, can't you?

MaskRay updated this revision to Diff 169114.Oct 10 2018, 3:35 PM

Use early exit

if (!Config->WarnSymbolOrdering ||
    (Sym->isUndefined() &&
     Config->UnresolvedSymbols == UnresolvedPolicy::Ignore))
ruiu added inline comments.Oct 10 2018, 3:39 PM
ELF/Symbols.cpp
268–271

It's a nit, but I wouldn't merge the two conditions to make it look nicer.

if (!Config->WarnSymbolOrdering)
  return;

// comment
if (Sym->isUndefined() && ...)
  return;

The first condition is obvious, and it is better not to mix it with some more complicated condition, which needs a comment.

MaskRay updated this revision to Diff 169116.Oct 10 2018, 3:45 PM

Use ruiu's preferred early-exit style

ruiu added inline comments.Oct 10 2018, 3:46 PM
ELF/Symbols.cpp
284

This is not related.

MaskRay marked 4 inline comments as done.Oct 10 2018, 3:47 PM
MaskRay added inline comments.
ELF/Symbols.cpp
284

I just made a change while you were commenting..

MaskRay marked 5 inline comments as done.Oct 10 2018, 3:47 PM
ruiu accepted this revision.Oct 10 2018, 3:48 PM

LGTM

This revision is now accepted and ready to land.Oct 10 2018, 3:48 PM
This revision was automatically updated to reflect the committed changes.