[PATCH] D24388: [ELF] Merge sections with different access attributes
Eugene Leviant via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 9 06:09:27 PDT 2016
evgeny777 created this revision.
evgeny777 added reviewers: ruiu, rafael.
evgeny777 added subscribers: grimar, ikudrin, llvm-commits.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.
There was a long story here of merging output sections when linker script is used and reverting it back to original scheme with multiple output sections having the same name. Now when we returned to original scheme, I'm getting troubles linking boot loader, where all code and data should be packed to a single section and then extracted from result image using objcopy.
To deal with this problem, I suggest dropping section access attributes from output section key and merging them in addSection(). This solves my problem and doesn't break unit tests, except repsection-va.s, which is part of linker script processor test suite.
I'd like to add that such behavior conforms to GNU linkers. Both gold and ld merge section attributes in such case.
Repository:
rL LLVM
https://reviews.llvm.org/D24388
Files:
ELF/OutputSections.cpp
ELF/OutputSections.h
test/ELF/linkerscript/repsection-va.s
Index: test/ELF/linkerscript/repsection-va.s
===================================================================
--- test/ELF/linkerscript/repsection-va.s
+++ test/ELF/linkerscript/repsection-va.s
@@ -7,9 +7,8 @@
# CHECK: Sections:
# CHECK-NEXT: Idx Name Size Address Type
# CHECK-NEXT: 0 00000000 0000000000000000
-# CHECK-NEXT: 1 .foo 00000004 0000000000000158 DATA
-# CHECK-NEXT: 2 .foo 00000004 000000000000015c DATA
-# CHECK-NEXT: 3 .text 00000001 0000000000000160 TEXT DATA
+# CHECK-NEXT: 1 .foo 00000008 0000000000000158 DATA
+# CHECK-NEXT: 2 .text 00000001 0000000000000160 TEXT DATA
.global _start
_start:
Index: ELF/OutputSections.h
===================================================================
--- ELF/OutputSections.h
+++ ELF/OutputSections.h
@@ -102,6 +102,7 @@
if (Alignment > Header.sh_addralign)
Header.sh_addralign = Alignment;
}
+ void updateFlags(InputSectionBase<ELFT> *C);
// If true, this section will be page aligned on disk.
// Typically the first section of each PT_LOAD segment has this flag.
Index: ELF/OutputSections.cpp
===================================================================
--- ELF/OutputSections.cpp
+++ ELF/OutputSections.cpp
@@ -56,6 +56,12 @@
}
template <class ELFT>
+void OutputSectionBase<ELFT>::updateFlags(InputSectionBase<ELFT> *C) {
+ this->Header.sh_flags |=
+ C->getSectionHdr()->sh_flags & (SHF_EXECINSTR | SHF_WRITE);
+}
+
+template <class ELFT>
GotPltSection<ELFT>::GotPltSection()
: OutputSectionBase<ELFT>(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
this->Header.sh_addralign = Target->GotPltEntrySize;
@@ -894,6 +900,7 @@
Sections.push_back(S);
S->OutSec = this;
this->updateAlignment(S->Alignment);
+ this->updateFlags(C);
}
// If an input string is in the form of "foo.N" where N is a number,
@@ -1252,6 +1259,7 @@
auto *Sec = cast<MergeInputSection<ELFT>>(C);
Sec->OutSec = this;
this->updateAlignment(Sec->Alignment);
+ this->updateFlags(C);
this->Header.sh_entsize = Sec->getSectionHdr()->sh_entsize;
Sections.push_back(Sec);
@@ -1868,7 +1876,8 @@
OutputSectionFactory<ELFT>::createKey(InputSectionBase<ELFT> *C,
StringRef OutsecName) {
const Elf_Shdr *H = C->getSectionHdr();
- uintX_t Flags = H->sh_flags & ~SHF_GROUP & ~SHF_COMPRESSED;
+ uintX_t Flags =
+ H->sh_flags & ~(SHF_GROUP | SHF_COMPRESSED | SHF_EXECINSTR | SHF_WRITE);
// For SHF_MERGE we create different output sections for each alignment.
// This makes each output section simple and keeps a single level mapping from
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24388.70817.patch
Type: text/x-patch
Size: 2700 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160909/e1587ac3/attachment.bin>
More information about the llvm-commits
mailing list