This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Postpone evaluation of ORIGIN/LENGTH in a MEMORY command
ClosedPublic

Authored by MaskRay on Mar 6 2020, 11:55 AM.

Details

Summary
createFiles(args)
 readDefsym
 readerLinkerScript(*mb)
  ...
   readMemory
    readMemoryAssignment("ORIGIN", "org", "o") // eagerly evaluated
target = getTarget();
link(args)
 writeResult<ELFT>()
  ...
   finalizeSections()
    script->processSymbolAssignments()
     addSymbol(cmd) // with this patch, evaluated here

readMemoryAssignment eagerly evaluates ORIGIN/LENGTH and returns an uint64_t.
This patch postpones the evaluation to make

  • --defsym and symbol assignments
  • CONSTANT(COMMONPAGESIZE) (requires a non-null lld::elf::target)

work. If the expression somehow requires interaction with memory
regions, the circular dependency may cause the expression to evaluate to
a strange value. See the new test added to memory-err.s

Diff Detail

Event Timeline

MaskRay created this revision.Mar 6 2020, 11:55 AM
aykevl added a subscriber: aykevl.Mar 6 2020, 1:26 PM
MaskRay updated this revision to Diff 248835.Mar 6 2020, 2:47 PM
MaskRay edited the summary of this revision. (Show Details)
MaskRay added reviewers: grimar, psmith, ruiu.

Add tests

grimar accepted this revision.Mar 7 2020, 1:41 AM

LGTM with 2 comments addressed.

lld/ELF/ScriptParser.cpp
1526

It calls std::function(nullptr_t) constructor.
Such Expr will fail during evaluation (exception: std::bad_function_call).

You should probably use return [] { return 0; };

lld/test/ELF/linkerscript/memory.s
49

I'd probably add a short description comment here and for the test below.

This revision is now accepted and ready to land.Mar 7 2020, 1:41 AM
MaskRay updated this revision to Diff 248932.Mar 7 2020, 8:03 AM
MaskRay marked 3 inline comments as done.

Address comments

lld/ELF/ScriptParser.cpp
1526

Thanks for this tip!

return 0 does not crash (not testable) because:

createFiles(args);  // parse linker scripts
if (errorCount())
  return;

Anyway, return [] { return 0; }; removes dependency on errorCount() check.

Adding myself as reviewer so I don't lose this patch. I hope to test this out soon.

MaskRay updated this revision to Diff 249007.Mar 8 2020, 9:57 AM

Add documentation docs/ELF/linker_script.rst

MaskRay updated this revision to Diff 249008.Mar 8 2020, 9:59 AM

Restore the previous Diff. Added docs/ELF/linker_script.rst to the wrong Differential.

This revision was automatically updated to reflect the committed changes.