This is an archive of the discontinued LLVM Phabricator instance.

[lld] Implement --dynamic-list
ClosedPublic

Authored by zatrazz on Apr 11 2016, 5:37 AM.

Details

Reviewers
ruiu
rafael
Summary

This patch implements the --dynamic-list option, which adds a list of
global symbol that either should not be bounded by default definition
when creating shared libraries, or add in dynamic symbol table in the
case of creating executables.

The patch modifies the ScriptParserBase class to use a list of Token
instead of StringRef, which contains information if the token is a
quoted or unquoted strings. It is used to use a faster search for
exact match symbol name.

The input file follow a similar format of linker script with some
simplifications (it does not have scope or node names). It leads
to a simplified parser define in DynamicList.{cpp,h}.

Different from ld/gold neither glob pattern nor mangled names
(extern 'C++') are currently supported.

Diff Detail

Event Timeline

zatrazz updated this revision to Diff 53225.Apr 11 2016, 5:37 AM
zatrazz retitled this revision from to [lld] Implement --dynamic-list.
zatrazz updated this object.
zatrazz added reviewers: ruiu, rafael.
zatrazz set the repository for this revision to rL LLVM.
zatrazz added a project: lld.
zatrazz added subscribers: llvm-commits, lld.
grimar added a subscriber: grimar.Apr 11 2016, 9:14 AM
grimar added inline comments.Apr 11 2016, 9:36 AM
ELF/DynamicList.cpp
50

Its a bit strange function name, there is standart (http://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly) saying that "Function names should be verb phrases (as they represent actions)"
So I would add "get":

getSupportedLanguage(StringRef Lang);

Probably "get" is not best word here, but it shows the idea. And also function name is uppercase, but should be lowercase.

116

Looks this can be simplified:

StringRef Entry = next();
if (Entry != "extern" || peek() == ";") {
  DynList->ExactMatch.insert(Entry);
  return;
}

StringRef Tok = next();
DynamicList::GlobLanguage Lang = SupportedLanguage(Tok);
if (Lang != DynamicList::LANGUAGE_NOT_SUPPORTED)
  readLanguageGroup(Lang);
else
  setError("invalid language in extern definition (" + Tok + ")");
121

You can remove brackets.

while (!atEOF())
  readGroup();
131

I would write:

return ExactMatch.find(Symbol) != ExactMatch.end();
ELF/Options.td
169

Not sorted.

zatrazz added inline comments.Apr 11 2016, 10:43 AM
ELF/DynamicList.cpp
50

In since language demangling is not really supported I will just remove this method.

116

Rui has asked to remove external demangling support, so I will simplify to just:

void DynamicListParser::readEntry() {
  DynList->ExactMatch.insert(next());
}
121

Ack.

zatrazz updated this revision to Diff 53279.Apr 11 2016, 10:46 AM
zatrazz removed rL LLVM as the repository for this revision.

Updated patch based on previous comments.

ruiu added inline comments.Apr 11 2016, 3:28 PM
ELF/Driver.cpp
42

I think it is better to not use DynList as a container of the list of dynamic list symbols. You can just add a new set to Config instead and use that as

if (Config->DynamicList.count(Sym.getName()))

or something like that.

143–149

You might want to make this piece of code a separate function because it is repeated at least twice.

ELF/DynamicList.cpp
35

You have an extra }.

65–67

I wouldn't make this a function because it's too short.

ELF/Writer.cpp
836–837 ↗(On Diff #53279)

Adding code here is not a good idea because this piece of code would be executed for all symbols. That's too expensive.

Instead of doing that, run a loop for each symbols in the dynamic list and set MustBeInDynSym flag. It's much cheaper.

zatrazz updated this revision to Diff 53396.Apr 12 2016, 8:09 AM

Updated patch based on previous comment.

ruiu added inline comments.Apr 12 2016, 12:24 PM
ELF/Config.h
54

Instead of adding DynamicList, please add DenseSet<StringRef>, because the simple set just works.

ELF/Driver.cpp
135

Since we handle errors inside this function, it is rather confusing to propagate a detailed error back to callers. I'd use llvm::Optional instead of ErrorOr.

136

Do you need this?

ELF/Writer.cpp
1115 ↗(On Diff #53396)

This comment needs to be more explanatory.

// The dyanmic list is a feature to give a list of symbols that need
// to be exported via the dynamic symbol table. Here is where the
// dynamic list is processed.
1124 ↗(On Diff #53396)

Why did you change this?

zatrazz added inline comments.Apr 12 2016, 12:48 PM
ELF/Config.h
54

Right, but since the idea is to visit each dynamic list entry to check against the Symtab symbols, why not just a std::vector<llvm::StringRef> as well?

ELF/Driver.cpp
42

Ack.

135

Ack.

136

I will remove it.

143–149

Ack.

ELF/DynamicList.cpp
35

Ack.

65–67

Ack.

ELF/Writer.cpp
1115 ↗(On Diff #53396)

Ack.

1124 ↗(On Diff #53396)

Because the list is already being copies above to be used in the dynamic list processing. Do we really need to get the mapvector again?

836–837 ↗(On Diff #53279)

Ack.

ruiu added inline comments.Apr 12 2016, 12:58 PM
ELF/Config.h
54

Yeah. Set felt to be a right choice because it is logically a set, but since we are using vector<StringRef> for other things that are logically sets (e.g. Undefined), it probably makes sense more to make this a vector.

ELF/Writer.cpp
1124 ↗(On Diff #53396)

I'm sorry but I don't get what you mean. SymtabSymbols is used only once here, so this seems to be just defining a redundant temporary variable and that makes a copy of the mapvector. Am I missing something?

zatrazz added inline comments.Apr 12 2016, 1:24 PM
ELF/Writer.cpp
1124 ↗(On Diff #53396)

My mistake, I notice I am using the Symtab::find method instead. I will change it back.

zatrazz updated this revision to Diff 53448.Apr 12 2016, 1:27 PM

Updated patch based on previous comments.

ruiu added inline comments.Apr 12 2016, 1:31 PM
ELF/Config.h
51–53

Sort.

ELF/Driver.h
25

Please don't use using in the header.

35

So you need to write llvm::Optional<...>

ELF/DynamicList.h
24–29

Now you can remove this class and replace it with readDynamicList function.

ELF/Writer.cpp
12 ↗(On Diff #53448)

Remove.

1116 ↗(On Diff #53448)

Remove {}

zatrazz updated this revision to Diff 53552.Apr 13 2016, 6:50 AM

Updated patch based on previous comments.

ruiu added inline comments.Apr 13 2016, 8:54 AM
ELF/Driver.cpp
104

Remove llvm:: (since in this .cpp file we have using namespace llvm.)

136

Ditto

149

Ditto

320–321

This place does not seems the right position to add this code because this looks different from other lines just above this one. I'd probably add this at end of this function.

ELF/DynamicList.cpp
17–24

Remove unused includes. I don't think we need Driver.h, for example.

26–29

Please remove unused ones.

ELF/DynamicList.h
14–16

Remove.

22

Remove.

ELF/Options.td
169

Yes, please sort.

ELF/Writer.cpp
1112–1117 ↗(On Diff #53552)

I don't think this piece of code needs to be added to this place. This function is large and complex, so no new code should be added unless it is absolutely needed. One way to avoid doing this is to move this code to SymbolTable.cpp just like scanShlibUndefines and call the new function from the driver.

grimar added inline comments.Apr 13 2016, 8:56 AM
test/ELF/invalid-dynamic-list.test
31

foobar, not foobaar

zatrazz updated this revision to Diff 53594.Apr 13 2016, 11:02 AM

Updated patch based on previous comments.

ruiu accepted this revision.Apr 13 2016, 11:19 AM
ruiu edited edge metadata.

LGTM with a few nits. Thanks!

ELF/DynamicList.cpp
16–23

Do you need Driver.h, FileSystem.h, Path.h and StringSaver.h?

ELF/DynamicList.h
14

You can remove StringSet.h no?

ELF/Options.td
48

Let's use the same help message as gold. Read a list of dynamic symbols

This revision is now accepted and ready to land.Apr 13 2016, 11:19 AM
zatrazz added inline comments.Apr 13 2016, 11:26 AM
ELF/DynamicList.cpp
16–23

Nops, I will remove it.

ELF/DynamicList.h
14

Yes, I will remove it.

ELF/Options.td
48

Ack.

zatrazz closed this revision.Apr 13 2016, 12:38 PM