This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Linkerscript: implement DATA_SEGMENT_RELRO_END.
ClosedPublic

Authored by grimar on Jul 26 2016, 8:45 AM.

Details

Summary

Description says:

DATA_SEGMENT_RELRO_END(offset, exp)
This defines the end of the PT_GNU_RELRO segment when -z relro' option is used. When -z relro' option is not present, DATA_SEGMENT_RELRO_END does nothing, otherwise DATA_SEGMENT_ALIGN is padded so that exp + offset is aligned to the most commonly used page boundary for particular target. If present in the linker script, it must always come in between DATA_SEGMENT_ALIGN and DATA_SEGMENT_END. Evaluates to the second argument plus any padding needed at the end of the PT_GNU_RELRO segment due to section alignment.

. = DATA_SEGMENT_RELRO_END(24, .);

(https://sourceware.org/binutils/docs/ld/Builtin-Functions.html)

This implementation is much simplier:

  1. I do not touch DATA_SEGMENT_ALIGN, it do what it do now - just aligns to the page boundary.
  2. When relro is disabled, then DATA_SEGMENT_RELRO_END is fully ignored (that is consistent with documentation).
  3. When -z relro is enabled, then: a) Parameters of DATA_SEGMENT_RELRO_END is ignored. That should be correct as it is usually just a 24 bytes shift that allows to protect first 3 entries of got.plt with relro. (https://svnweb.freebsd.org/base/head/sys/conf/ldscript.amd64?revision=284870&view=markup#l146). b) DATA_SEGMENT_RELRO_END just aligns to the page boundary. That is what expected because all sections that are not affected by relro should be on another memory page.

So at fact the difference with documented behavior is that I do not pad DATA_SEGMENT_ALIGN. 3 entries of got.plt are uncovered by relro, but functionality is simple and equal to lld behavior for case when script is not given.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar updated this revision to Diff 65530.Jul 26 2016, 8:45 AM
grimar retitled this revision from to [ELF] Linkerscript: implement DATA_SEGMENT_RELRO_END..
grimar updated this object.
grimar added reviewers: ruiu, rafael.
grimar added subscribers: llvm-commits, grimar, davide, evgeny777.
ruiu edited edge metadata.Jul 26 2016, 9:57 AM

It seems that it is not hard to implement exactly what is described in the document. Why don't you do that? Ignoring the parameters would be confusing.

In D22813#496244, @ruiu wrote:

It seems that it is not hard to implement exactly what is described in the document. Why don't you do that? Ignoring the parameters would be confusing.

We do not implement this behavior for lld without script (D20024).
Also I thing that requires 2 passes during assignAddress to calculate the required shift for DATA_SEGMENT_ALIGN, so it is not so simple also.
(First pass will iterate until meet the first non relro section and calculate the shift, second should shift the location counter at DATA_SEGMENT_ALIGN position and reassign addresses again).
Implementing it as this patch do at least should allow this to work now without that overcomplication.

ruiu added a comment.Jul 26 2016, 10:35 AM

Okay. This is a hairy feature which we probably don't want to fully support. Don't know how to communicate to users that our linker script semantics is different for this function. I was thinking of a warning message, but it can be too noisy. Maybe we should add a note in the documentation?

Anyways, please leave a comment so that we won't forget the fact that the feature is different from what GNU implements.

ELF/LinkerScript.cpp
826 ↗(On Diff #65530)

Add a short comment here saying that our implementation is different from GNU.

829 ↗(On Diff #65530)

This should be readExpr().

831–833 ↗(On Diff #65530)

Our semantics is different anyways, so we don't even have to look at Config->ZRelro. I'd always align to Target->PageSize.

This revision was automatically updated to reflect the committed changes.

Sorry I committed this with the fixes below. Was it LGTM ? If not I can revert.

ELF/LinkerScript.cpp
826 ↗(On Diff #65530)

Done.

829 ↗(On Diff #65530)

Done.

831–833 ↗(On Diff #65530)

Hmm. Ok, since we have -z relro by default anyways.

In D22813#496287, @ruiu wrote:

Okay. This is a hairy feature which we probably don't want to fully support. Don't know how to communicate to users that our linker script semantics is different for this function. I was thinking of a warning message, but it can be too noisy. Maybe we should add a note in the documentation?

I don't think users really will care about first 3 got.plt entry protection. So we can note about this in some general list of known difference, but I would probably not expect someone notice that at all.

In D22813#496419, @ruiu wrote:

LGTM

Thanks :)