This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Support PROVIDE and PROVIDE_HIDDEN within SECTIONS {} block
ClosedPublic

Authored by evgeny777 on Jul 21 2016, 5:34 AM.

Details

Reviewers
ruiu
Summary

Basic support for PROVIDE and PROVIDE_HIDDEN, currently only within SECTIONS

The existing parser does not validate expressions. To support PROVIDE(sym = expr), I implemented simple simple correctness validation based on brace counter. It aborts
reading expression tokens, if extra ')' is seen. This changed error message in one of the tests

Diff Detail

Event Timeline

evgeny777 updated this revision to Diff 64862.Jul 21 2016, 5:34 AM
evgeny777 retitled this revision from to [ELF] Support PROVIDE and PROVIDE_HIDDEN within SECTIONS {} block.
evgeny777 updated this object.
evgeny777 added a reviewer: ruiu.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.
evgeny777 added subscribers: grimar, ikudrin, llvm-commits.
ruiu added inline comments.Jul 21 2016, 5:48 AM
ELF/LinkerScript.cpp
350–351

Why did you remove {}?

521

This doesn't look beautiful. Isn't there any better way?

791

Let's name this readProvide as Body is used often to mean a symbol.

795

Create doesn't feel like a good name. How about Assign?

873–881

Is this change related to the feature you are adding in this patch?

ELF/LinkerScript.h
48

Please define this enum in SymbolAssignment class (as a non-enum class).

51

I wouldn't use a default argument unless it really improves to readability.

evgeny777 added inline comments.Jul 21 2016, 5:57 AM
ELF/LinkerScript.cpp
521

I need some flag, so that I don't override value of provided symbol later in assignAddresses, in case it is already defined somewhere. I'll think how to rewrite it, and open to suggestions.

873–881

Yes. As I said in summary, this is intended to early terminate the expression reader in case we see extra ')' bracket. Otherwise parser will eat tokens till it finds semicolon

grimar added inline comments.Jul 21 2016, 5:58 AM
ELF/LinkerScript.cpp
873–881

This should be fixed in separate patch.

test/ELF/linkerscript-symbols.s
43

somesym = 0
(just hard to read)

ruiu added inline comments.Jul 21 2016, 6:04 AM
ELF/LinkerScript.cpp
521

How about adding a SymbolBody* to SymbolAssignment class and set it to the return value of addAbsolute?

evgeny777 added inline comments.Jul 21 2016, 6:20 AM
ELF/LinkerScript.cpp
521

The problem is that current version overrides symbol value in case it is already defined (addAbsolute is not called) and is not assigned inside PROVIDE() or PROVIDE_HIDDEN(). So in case you specify "end = ." in script, the "end" symbol will be overridden, no matter has it been defined or not.

This was done in one of my previous patches in order to be able to override reserved symbols (end, etext, edata) in linker script, because currently they are always created in addReservedSymbols(). May be this should be fixed first, I don't know.

873–881

May be, but actually this parser improvement is only needed for PROVIDE(). I don't mind making separate review, but not sure if it's really needed. Rui, what's your opinion?

grimar added inline comments.Jul 21 2016, 6:26 AM
ELF/LinkerScript.cpp
873–881

Point here that this feature is useful itself and also should have a testcase which is unrelative to what this patch do. That not only make this patch a bit smaller, but also leaves this improvement in if patch be reverted, for example.

ruiu added inline comments.Jul 21 2016, 6:32 AM
ELF/LinkerScript.cpp
350–351

So, is it equivalent to Cmd->Provision == SymbolProvision::Create, no?

873–881

I don't think we even want it. If there's an error, it'll be found out, right?

evgeny777 added inline comments.Jul 21 2016, 6:44 AM
ELF/LinkerScript.cpp
350–351

Not exactly. It could also be SymbolProvision::Provide and SymbolProvision::ProvideHidden.

We set Provision to Ignore only when the following two conditions are met:
a) Initially Provision == Provide or Provsion == ProvideHidden
b) Symbol has been already defined (Symtab::find(Name) returns valid pointer)

In all other cases we should set the Symbol value

ruiu edited edge metadata.Jul 21 2016, 6:57 AM

I believe there's a better way, but it's probably too detailed and doesn't have to be done in this patch. But at least can you separate add a separate flag to record whether a symbol was present or not, so that we don't mutate parse results in an obscure way?

Also I believe you want to define two boolean members, Provide and Hidden, instead of one member that has a combination of the two variables.

evgeny777 updated this revision to Diff 64886.Jul 21 2016, 7:33 AM
evgeny777 edited edge metadata.

Review updated

ruiu added inline comments.Jul 21 2016, 12:35 PM
ELF/LinkerScript.cpp
513–514

Negate the condition to reduce the indentation level.

auto *Cmd = dyn_cast<...>(...);
if (!Cmd || Cmd->Name == ".")
  continue;
864

When you add { please add {} to the previous if (or else) clauses, so that they look the same.

873–881

Can you remove it?

evgeny777 added inline comments.Jul 21 2016, 1:27 PM
ELF/LinkerScript.cpp
873–881

What exactly? The "if (Tok == ";")" ? If so, how will we handle normal symbol assignments then? Like "mysym = 0;"

ruiu added inline comments.Jul 21 2016, 3:04 PM
ELF/LinkerScript.cpp
873–881

I meant the new code you added to this function in this patch.

evgeny777 added inline comments.Jul 21 2016, 3:09 PM
ELF/LinkerScript.cpp
873–881

The new code is used to stop reading expression in case extra ')' is seen in expression.
This happens in the case below:
PROVIDE(a = 100);

If you want this code to be removed then please suggest how to handle the case above, because ')' will be read as part of expression otherwise.

ruiu added a comment.Jul 21 2016, 3:35 PM

Essentially looks good. Please upload the latest patch with all review comments applied. Thanks.

ELF/LinkerScript.cpp
873–881

Ah, I think I finally understood why you added this code. It makes sense. But please add a function comment saying that this function reads a balanced expression until ";".

evgeny777 updated this revision to Diff 64987.Jul 21 2016, 4:19 PM
evgeny777 removed rL LLVM as the repository for this revision.

Review updated

ruiu accepted this revision.Jul 21 2016, 4:29 PM
ruiu edited edge metadata.

LGTM with a nit.

ELF/LinkerScript.cpp
877

This look a bit tricky. Straightforward code would be

if (Tok == "(")
  ++Braces;
else if (Tok == ")")
  --Braces;
This revision is now accepted and ready to land.Jul 21 2016, 4:29 PM
emaste added a subscriber: emaste.Jul 21 2016, 4:45 PM
evgeny777 closed this revision.Jul 22 2016, 3:11 AM