This is an archive of the discontinued LLVM Phabricator instance.

[ELF] - Linkerscript: implemented SUBALIGN() command.
ClosedPublic

Authored by grimar on Aug 2 2016, 7:20 AM.

Details

Summary

You can force input section alignment within an output section by using SUBALIGN. The
value specified overrides any alignment given by input sections, whether larger or smaller.

SUBALIGN is used in many projects in the wild, for example:

https://github.com/kubo39/tinycr/blob/536a8a0ba290b08659d347a0bdddb966cff44441/script.ld
https://github.com/def-/nim-small-coreutils/blob/3cb5e99ab8435220c82b9c307ce8909841655cc8/tools/x86_64/script.ld
https://github.com/takeneco/uniqos/blob/57e802d54979f1f02942e0260687c417e46c58df/arch/x86_64/boot/fd/bootsect/bootsect.ld
https://github.com/sjrct/Frosk/blob/13ee75a64ae98c652c32795bcc5d17ae459d2cfc/kernel/kernel.ld

and many others.

Patch implements it with a single restriction: access to location counter in expression is forbidden. That should not be a problem
as every script I saw uses just integer value here. And the reasons of that is that we assign offsets before we know VA of section,
so we do not know the location counter value. Solution would be to layout input sections right before assign address to output section I guess,
but as I mentioned before that does not seems reasonable to implement for this command.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar updated this revision to Diff 66472.Aug 2 2016, 7:20 AM
grimar retitled this revision from to [ELF] - Linkerscript: implemented SUBALIGN() command..
grimar updated this object.
grimar added reviewers: ruiu, rafael.
grimar added subscribers: llvm-commits, grimar, davide, evgeny777.
ruiu edited edge metadata.Aug 2 2016, 3:34 PM

I think that it is better to overwrite each input section's Alignment member variable.

ELF/LinkerScript.h
29–30 ↗(On Diff #66472)

Hmm, this seems too complicated.

85 ↗(On Diff #66472)

I'd treat "subalign" as one word, so I'd name SubalignExpr.

ruiu added inline comments.Aug 2 2016, 4:04 PM
ELF/LinkerScript.cpp
350 ↗(On Diff #66472)

If you want to detect this error, you need to do this at parse time rather than calculation time. Being said that, I think we should just ignore the error as it complicates the code by introducing DotExpr type.

grimar updated this revision to Diff 68363.Aug 17 2016, 8:31 AM
grimar edited edge metadata.
  • Addressed review comments.
ruiu added inline comments.Aug 17 2016, 12:26 PM
ELF/LinkerScript.cpp
289 ↗(On Diff #68363)

Do not call SubalignExpr in this loop because it's a constant value.

630 ↗(On Diff #68363)

SubAlign -> Subalign.

915 ↗(On Diff #68363)

Use readParenExpr.

grimar updated this revision to Diff 68489.Aug 18 2016, 12:29 AM
  • Addressed review comments.
grimar added inline comments.Aug 18 2016, 6:22 AM
ELF/LinkerScript.cpp
289 ↗(On Diff #68363)

Yes, I thought about that when wrote that initially. Did it to simplify the code a bit. There should be not many output sections and probably none or just few of them them will use SUBALIGN(), so selected one line shorter way.
Fixed.

915 ↗(On Diff #68363)

Done.

ELF/LinkerScript.h
85 ↗(On Diff #66472)

Done.

ruiu added inline comments.Aug 18 2016, 1:32 PM
ELF/LinkerScript.cpp
287 ↗(On Diff #68489)

Alignment can never be 0 (in LLD we canonicalize 1 as 0). So how about setting Sublign to 0 if SubalignExpr is absent?

289 ↗(On Diff #68489)

Then you can do

if (Subalign)
  Sec->Alignment = Subalign;
grimar updated this revision to Diff 68655.Aug 19 2016, 1:22 AM
  • Addressed review comments.
ruiu accepted this revision.Aug 19 2016, 7:57 AM
ruiu edited edge metadata.

LGTM

This revision is now accepted and ready to land.Aug 19 2016, 7:57 AM
This revision was automatically updated to reflect the committed changes.