This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Add Section() getter to expression structure (Expr)
ClosedPublic

Authored by evgeny777 on Oct 10 2016, 10:53 AM.

Details

Summary

This allows doing 2 things:

  1. Correctly handle symbol assignments containing other symbols and ADDR() function when there is no SECTION block. So one can have script containing just these lines:
PROVIDE_HIDDEN(_begin_text = _start);
PROVIDE_HIDDEN(_end_text = ADDR(.text) + SIZEOF(.text));
  1. Make symbols containing ADDR() function synthetic.

Both _begin_text and _end_text from example above will be relative to .text section

Diff Detail

Repository
rL LLVM

Event Timeline

evgeny777 updated this revision to Diff 74145.Oct 10 2016, 10:53 AM
evgeny777 retitled this revision from to [ELF] Make symbols containing ADDR() function synthetic..
evgeny777 updated this object.
evgeny777 added reviewers: ruiu, rafael.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.
evgeny777 added subscribers: grimar, ikudrin, llvm-commits.
ruiu edited edge metadata.Oct 10 2016, 12:06 PM

The semantics implemented here is obscure and magical. ADDR() expression has a lingering effect to the following expressions. So it in some sense set a global context for an entire expression, even though it looks just like an expression. Do you really want it?

Unfortunately I have scripts which depend on this feature and which I can't change. Absolute value of address has two main problems:

  1. relocatable object files (you get incorrect value after final link)
  2. dynamic relocs for absolute symbols are not created.

Do you have an idea how to do this in more elegant way?

ruiu added a comment.Oct 10 2016, 12:27 PM

Currently we are handling "." as an absolute address and convert it to a section-relative values depending on a context. It doesn't fit well to the thing you are trying to implement because we cannot infer whether an assignment should create a section symbol or an absolute symbol. Surely you could add an attribute to an Expr, but it's not clean because an expression is no longer just an expression with that change.

I think the proper way of supporting it is to convert the type of Dot from (uint64_t) to (uint64_t, Section) where Section is a section if it is an section symbol, or a null if it is an absolute symbol. With that change, we can explain the ADDR()'s tricky behavior pretty naturally.

How is this extra 'Section' parameter proposed to be used? Is it just for consistency?

The problem is that expression evaluation is done too late: after symbols are created and even after scanRelocs is called. This means that necessary dynamic relocs won't be created. Besides that regular to synthetic conversion will be required for symbols.

ruiu added inline comments.Oct 13 2016, 3:51 PM
ELF/LinkerScript.cpp
1480–1484 ↗(On Diff #74145)

Theoretically, you need to propagate Section value not only for + or - but for all binary operators, no? I wonder if we should just add a member variable StringRef AddExprSection to ScriptParser and set it when we read "ADDR" expression. Then we can check the value in readAssignment. It's a bit dirty but is probably practical.

ELF/LinkerScript.h
43 ↗(On Diff #74145)

A std::function is not a pointer. It has operator bool, so it should be

operator bool() const { return Fn; }
evgeny777 added inline comments.Oct 17 2016, 3:17 AM
ELF/LinkerScript.cpp
1480–1484 ↗(On Diff #74145)

Theoretically, you need to propagate Section value not only for + or - but for all binary operators, no?

I think you don't have to do this for '*' and '/', because it's senseless (gold doesn't do this either). The 'AddExprSection' should work, but one has to propagate it to SymbolAssignment at any given point of call to Expression().

BTW, may be you take a look at https://reviews.llvm.org/D25560 ?
It works for me either and is much shorter at the same time.

evgeny777 updated this revision to Diff 77818.Nov 14 2016, 8:52 AM
evgeny777 retitled this revision from [ELF] Make symbols containing ADDR() function synthetic. to [ELF] Add Section() getter to expression structure (Expr).
evgeny777 updated this object.
evgeny777 edited edge metadata.
evgeny777 removed rL LLVM as the repository for this revision.

Implementation was changed, as https://reviews.llvm.org/D25560 seems to be not correct

ruiu added inline comments.Nov 14 2016, 1:23 PM
ELF/LinkerScript.cpp
78 ↗(On Diff #77818)

bee -> been

85–88 ↗(On Diff #77818)

I think I'm missing something, but eventually you'll set ->Value for all symbols, right? What's the point of doing it earlier for some case?

869 ↗(On Diff #77818)

Add a function comment about what this function is for.

1494 ↗(On Diff #77818)

Use a concrete type instead of auto.

ELF/LinkerScript.h
46 ↗(On Diff #77818)

Please add a comment what this function is.

evgeny777 added inline comments.Nov 15 2016, 2:33 AM
ELF/LinkerScript.cpp
85–88 ↗(On Diff #77818)

If you don't list sections in linker script (HasSections is false), then all sections have already been created by the time addRegular or addSynthetic is called. In this case symbol values should be set immediately, because assignAddresses will not be called. See comment above in addRegular.

evgeny777 updated this revision to Diff 77977.Nov 15 2016, 4:15 AM

Addressed review comments

ruiu accepted this revision.Nov 15 2016, 11:07 AM
ruiu edited edge metadata.

LGTM

ELF/LinkerScript.h
47–48 ↗(On Diff #77977)

Nice comment.

This revision is now accepted and ready to land.Nov 15 2016, 11:07 AM
This revision was automatically updated to reflect the committed changes.