summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-10-14 19:21:25 +0000
committerRui Ueyama <ruiu@google.com>2015-10-14 19:21:25 +0000
commit4fcadaf5e747be3f00d45c9ae8a9ebd5c7ce6ac6 (patch)
treef3c71bbf95877d67a2915861d19125abb18304ea
parenta7f8f252647e414cbbfa84f542fae85d61757a55 (diff)
downloadbcm5719-llvm-4fcadaf5e747be3f00d45c9ae8a9ebd5c7ce6ac6.tar.gz
bcm5719-llvm-4fcadaf5e747be3f00d45c9ae8a9ebd5c7ce6ac6.zip
ELF2: Merge .{text,rodata,data,bss}.* sections.
Previously, we used input section names as output section names. That resulted that we created lots of sections for comdat or -f{function,data}-section sections. This patch reduces the number of sections by dropping suffix from all section names which start with ".text.", ".rodata.", ".data." or ".bss.". GNU linker does this using the internal linker script, but for LLD I chose to do that directly. Interestingly, this makes the linker faster. Time to link Clang is this. Before: real 0m0.537s user 0m0.433s sys 0m0.104s After: real 0m0.390s user 0m0.268s sys 0m0.120s It make sense because previously we created 57659 sections now only 27. llvm-svn: 250315
-rw-r--r--lld/ELF/Writer.cpp15
-rw-r--r--lld/test/elf2/section-name.s30
2 files changed, 44 insertions, 1 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 3af58b2143e..4307b48f034 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -369,6 +369,18 @@ static void addCommonSymbols(std::vector<DefinedCommon<ELFT> *> &Syms) {
Out<ELFT>::Bss->setSize(Off);
}
+static StringRef getOutputName(StringRef S) {
+ if (S.startswith(".text."))
+ return ".text";
+ if (S.startswith(".rodata."))
+ return ".rodata";
+ if (S.startswith(".data."))
+ return ".data";
+ if (S.startswith(".bss."))
+ return ".bss";
+ return S;
+}
+
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::createSections() {
// .interp needs to be on the first page in the output file.
@@ -403,7 +415,8 @@ template <class ELFT> void Writer<ELFT>::createSections() {
continue;
const Elf_Shdr *H = C->getSectionHdr();
uintX_t OutFlags = H->sh_flags & ~SHF_GROUP;
- SectionKey<ELFT::Is64Bits> Key{C->getSectionName(), H->sh_type, OutFlags};
+ SectionKey<ELFT::Is64Bits> Key{getOutputName(C->getSectionName()),
+ H->sh_type, OutFlags};
OutputSection<ELFT> *&Sec = Map[Key];
if (!Sec) {
Sec = new (CAlloc.Allocate())
diff --git a/lld/test/elf2/section-name.s b/lld/test/elf2/section-name.s
new file mode 100644
index 00000000000..783dfa99ad6
--- /dev/null
+++ b/lld/test/elf2/section-name.s
@@ -0,0 +1,30 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld2 %t -o %tout
+# RUN: llvm-readobj -sections %tout | FileCheck %s
+# REQUIRES: x86
+
+.global _start
+.text
+_start:
+
+.section .text.a,"ax"
+.section .text.,"ax"
+.section .rodata.a,"a"
+.section .rodata,"a"
+.section .data.a,"aw"
+.section .data,"aw"
+.section .bss.a,"",@nobits
+.section .bss,"",@nobits
+.section .foo.a,"aw"
+.section .foo,"aw"
+
+// CHECK-NOT: Name: .rodata.a
+// CHECK: Name: .rodata
+// CHECK-NOT: Name: .text.a
+// CHECK: Name: .text
+// CHECK-NOT: Name: .data.a
+// CHECK: Name: .data
+// CHECK: Name: .foo.a
+// CHECK: Name: .foo
+// CHECK-NOT: Name: .bss.a
+// CHECK: Name: .bss
OpenPOWER on IntegriCloud