This is an archive of the discontinued LLVM Phabricator instance.

[lld-macho] Implement option: -undefined TREATMENT
ClosedPublic

Authored by gkm on Dec 14 2020, 6:35 PM.

Details

Reviewers
int3
Group Reviewers
Restricted Project
Commits
rGcc1cf6332a30: [lld-macho] Implement option: -undefined TREATMENT
Summary

TREATMENT can be error, warning, suppress, or dynamic_lookup
The dymanic_lookup remains unimplemented for now.

Diff Detail

Event Timeline

gkm created this revision.Dec 14 2020, 6:35 PM
gkm requested review of this revision.Dec 14 2020, 6:35 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 14 2020, 6:35 PM
int3 added a subscriber: int3.Dec 14 2020, 10:17 PM
int3 added inline comments.
lld/MachO/Config.h
33–39

it doesn't look like we're actually using the numeric values, so we don't need to assign them. (: unsigned is likewise unnecessary)

lld/MachO/Driver.cpp
611–612

I think it would be nice set the treatment to ::error if the option argument is invalid. Then we won't need to handle the unknown case later on

lld/MachO/SymbolTable.cpp
158–159

can these be StringRefs?

176

with the change suggested above, this could be llvm_unreachable instead of fatal

lld/MachO/SymbolTable.h
58

I think this function is a verb-y function but the current name is noun-ish. How about naming it treatUndefinedSymbol? (ELF/COFF use reportUndefinedSymbol, but since we're not always going to report it...)

lld/MachO/Writer.cpp
415

doesn't seem like undefinedSymbol's return value is used anywhere. Can it just be a void function?

gkm marked 6 inline comments as done.Dec 15 2020, 8:06 PM
gkm added inline comments.
lld/MachO/SymbolTable.cpp
176

I dropped default: entirely, because clang warns that it is unused as every enum case is explicitly handled.

lld/MachO/SymbolTable.h
58

Since the API differs, I chose treatUndefinedSymbol()

lld/MachO/Writer.cpp
415

The bool was intended to accommodate use for the config->outputType == MH_EXECUTE case in lld::macho::link(), but I think it should always error() there. I made it void, since that intention was unrealized. We can always revise to return bool if/when we have a real use for it.

gkm marked 3 inline comments as done.Dec 15 2020, 11:44 PM
gkm added inline comments.
lld/MachO/SymbolTable.cpp
176

I thought I could drop unknown from the enum, but that wasn't workable for giving a diagnostic on StringSwitch<UndefinedSymbolTreatment>(...).Default(...), so default: llvm_unreachable() is necessary after all.

gkm updated this revision to Diff 312126.Dec 15 2020, 11:44 PM
  • respond to review feedback
  • add test case
int3 accepted this revision.Dec 16 2020, 7:16 AM

lgtm

lld/MachO/SymbolTable.cpp
176

you could also have case UndefinedSymbolTreatment::unknown: instead of default: (while retaining the llvm_unreachable) -- that way we still benefit from Clang's exhaustiveness checks

177

s/unkown/unknown/

lld/test/MachO/invalid/undefined-symbol.s
13–14

fwiw it appears that the ELF and COFF ports use the following format:

error: undefined symbol: $SYM
>>> referenced by $FILE

but we can always tweak our format later on

This revision is now accepted and ready to land.Dec 16 2020, 7:16 AM
gkm marked 3 inline comments as done.Dec 16 2020, 9:45 AM
gkm updated this revision to Diff 312245.Dec 16 2020, 9:49 AM
  • finalize according to review feedback
int3 added inline comments.Dec 16 2020, 10:25 AM
lld/test/MachO/invalid/stub-link.s
11–12

this string should probably be changed too?

lld/test/MachO/treat-undef-sym.s
15

one final nit: why not include the filename here too? Or, if we're just interested in checking for error vs warning, then we could just leave out the check for the "referenced by" line. Checking that those two words exist in isolation doesn't seem super useful...

(thanks for changing the format string btw)

smeenai added inline comments.
lld/MachO/SymbolTable.cpp
160

Nit: using empty for this purpose is more idiomatic than size.

gkm updated this revision to Diff 312560.Dec 17 2020, 10:49 AM
  • Use .empty() rather than .size() != 0 for existence check
gkm marked 3 inline comments as done.Dec 17 2020, 11:53 AM
gkm added inline comments.
lld/test/MachO/invalid/stub-link.s
11–12

Ah, I missed this one because it is unsupported on Darwin. I will also test on Linux.

lld/test/MachO/treat-undef-sym.s
15

The intention is to verify that the >>> referenced by line occurs. The complete line would include the object filename %t.o, but %t is not available in that context.

int3 added inline comments.Dec 17 2020, 11:58 AM
lld/test/MachO/treat-undef-sym.s
15

why not make %t available then via -DFILE?

gkm updated this revision to Diff 312580.Dec 17 2020, 12:07 PM
gkm marked 2 inline comments as done.
  • Fix "undefined symbol:" expected strings in more tests
gkm updated this revision to Diff 312647.Dec 17 2020, 4:48 PM
  • s/Twine/std::string/ for message in treatUndefinedSymbol()
This revision was automatically updated to reflect the committed changes.
thakis added a subscriber: thakis.Jan 9 2021, 6:03 PM

As far as I can tell, ld64 only accepts -undefined warning and -undefined suppress with -flat_namespace (which lld/MachO doesn't yet implement). That makes sense since with a flat namespace the undefineds can be found at dynamic link time, but with two-level lookup they can't since they containing framework isn't known (…right?).

Is it intentional that we deviate from ld64 here?

% clang main.c -Wl,-undefined,suppress
ld: can't use -undefined warning or suppress with -twolevel_namespace
clang: error: linker command failed with exit code 1 (use -v to see invocation)
% clang main.c -Wl,-undefined,warning
ld: can't use -undefined warning or suppress with -twolevel_namespace
clang: error: linker command failed with exit code 1 (use -v to see invocation)
gkm added a comment.Jan 11 2021, 6:06 PM

@thakis, that's a bug. There is no reason to deviate from ld64.