summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp2
-rw-r--r--lld/ELF/Writer.cpp14
-rw-r--r--lld/ELF/Writer.h3
-rw-r--r--lld/test/ELF/relocatable-sections.s30
4 files changed, 37 insertions, 12 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index b0a83d8d5cf..aa01d537558 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -345,7 +345,7 @@ void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
for (InputSectionBase<ELFT> *S : F->getSections())
if (!isDiscarded(S) && !S->OutSec)
- addSection(Factory, S, getOutputSectionName(S));
+ addSection(Factory, S, getOutputSectionName(S->Name));
}
// Sets value of a section-defined symbol. Two kinds of
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index d2ee56e74a2..dd29d5ef384 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -89,9 +89,10 @@ private:
};
} // anonymous namespace
-template <class ELFT>
-StringRef elf::getOutputSectionName(InputSectionBase<ELFT> *S) {
- StringRef Name = S->Name;
+StringRef elf::getOutputSectionName(StringRef Name) {
+ if (Config->Relocatable)
+ return Name;
+
for (StringRef V :
{".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.",
".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
@@ -712,7 +713,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
}
OutputSectionBase<ELFT> *Sec;
bool IsNew;
- std::tie(Sec, IsNew) = Factory.create(IS, getOutputSectionName(IS));
+ std::tie(Sec, IsNew) = Factory.create(IS, getOutputSectionName(IS->Name));
if (IsNew)
OutputSections.push_back(Sec);
Sec->addSection(IS);
@@ -1444,11 +1445,6 @@ template bool elf::isRelroSection<ELF32BE>(OutputSectionBase<ELF32BE> *);
template bool elf::isRelroSection<ELF64LE>(OutputSectionBase<ELF64LE> *);
template bool elf::isRelroSection<ELF64BE>(OutputSectionBase<ELF64BE> *);
-template StringRef elf::getOutputSectionName<ELF32LE>(InputSectionBase<ELF32LE> *);
-template StringRef elf::getOutputSectionName<ELF32BE>(InputSectionBase<ELF32BE> *);
-template StringRef elf::getOutputSectionName<ELF64LE>(InputSectionBase<ELF64LE> *);
-template StringRef elf::getOutputSectionName<ELF64BE>(InputSectionBase<ELF64BE> *);
-
template void elf::reportDiscarded<ELF32LE>(InputSectionBase<ELF32LE> *);
template void elf::reportDiscarded<ELF32BE>(InputSectionBase<ELF32BE> *);
template void elf::reportDiscarded<ELF64LE>(InputSectionBase<ELF64LE> *);
diff --git a/lld/ELF/Writer.h b/lld/ELF/Writer.h
index 4d9df9302bb..cf1c56019b8 100644
--- a/lld/ELF/Writer.h
+++ b/lld/ELF/Writer.h
@@ -41,8 +41,7 @@ struct PhdrEntry {
bool HasLMA = false;
};
-template <class ELFT>
-llvm::StringRef getOutputSectionName(InputSectionBase<ELFT> *S);
+llvm::StringRef getOutputSectionName(llvm::StringRef Name);
template <class ELFT> void reportDiscarded(InputSectionBase<ELFT> *IS);
diff --git a/lld/test/ELF/relocatable-sections.s b/lld/test/ELF/relocatable-sections.s
new file mode 100644
index 00000000000..bcc2b04dd7e
--- /dev/null
+++ b/lld/test/ELF/relocatable-sections.s
@@ -0,0 +1,30 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: ld.lld -r %t1.o -o %t
+# RUN: llvm-objdump -section-headers %t | FileCheck %s
+
+# CHECK: .text
+# CHECK-NEXT: .text._init
+# CHECK-NEXT: .text._fini
+# CHECK-NEXT: .rela.text
+# CHECK-NEXT: .rela.text._init
+# CHECK-NEXT: .rela.text._fini
+
+.globl _start
+_start:
+ call foo
+ nop
+
+.section .xxx,"a"
+ .quad 0
+
+.section .text._init,"ax"
+ .quad .xxx
+foo:
+ call bar
+ nop
+
+
+.section .text._fini,"ax"
+ .quad .xxx
+bar:
+ nop
OpenPOWER on IntegriCloud