[PATCH] D58892: [ELF] Split RW PT_LOAD on the PT_GNU_RELRO boundary
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 3 22:41:28 PST 2019
MaskRay created this revision.
Herald added subscribers: llvm-commits, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
Old: PT_LOAD(PT_GNU_RELRO(.data.rel.ro .bss.rel.ro) .data .bss)
New: PT_LOAD(PT_GNU_RELRO(.data.rel.ro .bss.rel.ro)) PT_LOAD(.data. .bss)
By having two PT_LOAD segments, we can utilize NOBITS and save bytes for
.bss.rel.ro.
.bss.rel.ro is currently small and only used by copy relocations of
symbols in read-only segments, but it can be used for other purposes in
the future, e.g. if a relro section's statically relocated data is all
zeros, we can move it to .bss.rel.ro.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D58892
Files:
ELF/Writer.cpp
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -1945,6 +1945,29 @@
Load->add(Out::ElfHeader);
Load->add(Out::ProgramHeaders);
+ // PT_GNU_RELRO includes all sections that should be marked as
+ // read-only by dynamic linker after proccessing relocations.
+ // Current dynamic loaders only support one PT_GNU_RELRO PHDR, give
+ // an error message if more than one PT_GNU_RELRO PHDR is required.
+ PhdrEntry *RelRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R);
+ bool InRelroPhdr = false;
+ OutputSection *RelroEnd = nullptr;
+ for (OutputSection *Sec : OutputSections) {
+ if (!needsPtLoad(Sec))
+ continue;
+ if (isRelroSection(Sec)) {
+ InRelroPhdr = true;
+ if (!RelroEnd)
+ RelRo->add(Sec);
+ else
+ error("section: " + Sec->Name + " is not contiguous with other relro" +
+ " sections");
+ } else if (InRelroPhdr) {
+ InRelroPhdr = false;
+ RelroEnd = Sec;
+ }
+ }
+
for (OutputSection *Sec : OutputSections) {
if (!(Sec->Flags & SHF_ALLOC))
break;
@@ -1962,7 +1985,8 @@
if (((Sec->LMAExpr ||
(Sec->LMARegion && (Sec->LMARegion != Load->FirstSec->LMARegion))) &&
Load->LastSec != Out::ProgramHeaders) ||
- Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) {
+ Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags ||
+ Sec == RelroEnd) {
Load = AddHdr(PT_LOAD, NewFlags);
Flags = NewFlags;
@@ -1983,28 +2007,6 @@
if (OutputSection *Sec = In.Dynamic->getParent())
AddHdr(PT_DYNAMIC, Sec->getPhdrFlags())->add(Sec);
- // PT_GNU_RELRO includes all sections that should be marked as
- // read-only by dynamic linker after proccessing relocations.
- // Current dynamic loaders only support one PT_GNU_RELRO PHDR, give
- // an error message if more than one PT_GNU_RELRO PHDR is required.
- PhdrEntry *RelRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R);
- bool InRelroPhdr = false;
- bool IsRelroFinished = false;
- for (OutputSection *Sec : OutputSections) {
- if (!needsPtLoad(Sec))
- continue;
- if (isRelroSection(Sec)) {
- InRelroPhdr = true;
- if (!IsRelroFinished)
- RelRo->add(Sec);
- else
- error("section: " + Sec->Name + " is not contiguous with other relro" +
- " sections");
- } else if (InRelroPhdr) {
- InRelroPhdr = false;
- IsRelroFinished = true;
- }
- }
if (RelRo->FirstSec)
Ret.push_back(RelRo);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58892.189118.patch
Type: text/x-patch
Size: 2573 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190304/883db68d/attachment.bin>
More information about the llvm-commits
mailing list