[lld] r326137 - Keep flags from phantom synthetic sections.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 26 14:32:15 PST 2018
Author: rafael
Date: Mon Feb 26 14:32:15 2018
New Revision: 326137
URL: http://llvm.org/viewvc/llvm-project?rev=326137&view=rev
Log:
Keep flags from phantom synthetic sections.
This fixes pr36475.
I think this code can be simplified a bit, but I would like to check
in the more direct fix if we are in agreement on the direction and
then refactor.
This is not something that bfd does. The issue is not noticed in bfd
because it keeps fewer sections from the linkerscript in the output.
The reasons why it seems reasonable to do this:
- As George noticed, we would still keep the flags if the output
section had both an empty synthetic section and a regular section
- We need an heuristic to find the flags of output sections. Using the
flags of a synthetic section that would have been there seems a
reasonable heuristic.
Added:
lld/trunk/test/ELF/pr36475.s
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/ELF/linkerscript/empty-synthetic-removed-flags.s
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=326137&r1=326136&r2=326137&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Mon Feb 26 14:32:15 2018
@@ -752,25 +752,6 @@ void LinkerScript::assignOffsets(OutputS
}
}
-static bool isAllSectionDescription(const OutputSection &Cmd) {
- // We do not remove empty sections that are explicitly
- // assigned to any segment.
- if (!Cmd.Phdrs.empty())
- return false;
-
- // We do not want to remove sections that have custom address or align
- // expressions set even if them are empty. We keep them because we
- // want to be sure that any expressions can be evaluated and report
- // an error otherwise.
- if (Cmd.AddrExpr || Cmd.AlignExpr || Cmd.LMAExpr)
- return false;
-
- for (BaseCommand *Base : Cmd.SectionCommands)
- if (!isa<InputSectionDescription>(*Base))
- return false;
- return true;
-}
-
void LinkerScript::adjustSectionsBeforeSorting() {
// If the output section contains only symbol assignments, create a
// corresponding output section. The issue is what to do with linker script
@@ -803,7 +784,7 @@ void LinkerScript::adjustSectionsBeforeS
continue;
}
- if (!isAllSectionDescription(*Sec))
+ if (!Sec->isAllSectionDescription())
Sec->Flags = Flags;
else
Cmd = nullptr;
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=326137&r1=326136&r2=326137&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Feb 26 14:32:15 2018
@@ -76,6 +76,25 @@ OutputSection::OutputSection(StringRef N
Live = false;
}
+bool OutputSection::isAllSectionDescription() const {
+ // We do not remove empty sections that are explicitly
+ // assigned to any segment.
+ if (!Phdrs.empty())
+ return false;
+
+ // We do not want to remove sections that have custom address or align
+ // expressions set even if them are empty. We keep them because we
+ // want to be sure that any expressions can be evaluated and report
+ // an error otherwise.
+ if (AddrExpr || AlignExpr || LMAExpr)
+ return false;
+
+ for (BaseCommand *Base : SectionCommands)
+ if (!isa<InputSectionDescription>(*Base))
+ return false;
+ return true;
+}
+
// We allow sections of types listed below to merged into a
// single progbits section. This is typically done by linker
// scripts. Merging nobits and progbits will force disk space
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=326137&r1=326136&r2=326137&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Mon Feb 26 14:32:15 2018
@@ -42,6 +42,8 @@ class OutputSection final : public BaseC
public:
OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
+ bool isAllSectionDescription() const;
+
static bool classof(const SectionBase *S) {
return S->kind() == SectionBase::Output;
}
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=326137&r1=326136&r2=326137&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Feb 26 14:32:15 2018
@@ -1383,9 +1383,9 @@ static void removeUnusedSyntheticSection
llvm::erase_if(ISD->Sections,
[=](InputSection *IS) { return IS == SS; });
- // If there are no other alive input sections left, we remove output
- // section from the output.
- if (getInputSections(OS).empty())
+ // If there are no other alive sections or commands left in the output
+ // section description, we remove it from the output.
+ if (getInputSections(OS).empty() && OS->isAllSectionDescription())
OS->Live = false;
}
}
Modified: lld/trunk/test/ELF/linkerscript/empty-synthetic-removed-flags.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/empty-synthetic-removed-flags.s?rev=326137&r1=326136&r2=326137&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/empty-synthetic-removed-flags.s (original)
+++ lld/trunk/test/ELF/linkerscript/empty-synthetic-removed-flags.s Mon Feb 26 14:32:15 2018
@@ -5,10 +5,9 @@
# RUN: llvm-readobj -s %t | FileCheck %s
## We have ".got.plt" synthetic section with SHF_ALLOC|SHF_WRITE flags.
-## It is empty, so linker removes it, but it have to keep ".got.plt" output
-## section because of BYTE command. Here we check that result output section
-## gets the same flags as previous allocatable section and does not get
-## SHF_WRITE flag from removed syntethic input section.
+## It is empty, so linker removes it, but it has to keep ".got.plt" output
+## section because of the BYTE command. Here we check that the output section
+## still remembers what the flags of .got.plt are.
# CHECK: Section {
# CHECK: Index: 2
@@ -16,13 +15,22 @@
# CHECK-NEXT: Type: SHT_PROGBITS
# CHECK-NEXT: Flags [
# CHECK-NEXT: SHF_ALLOC
-# CHECK-NEXT: SHF_EXECINSTR
+# CHECK-NEXT: SHF_WRITE
# CHECK-NEXT: ]
-## Check flags are the same if we omit empty synthetic section in script.
+## Check flags are not the same if we omit empty synthetic section in script.
# RUN: echo "SECTIONS { .foo : { *(.foo) } .bar : { BYTE(0x11) }}" > %t.script
# RUN: ld.lld -o %t --script %t.script %t.o
-# RUN: llvm-readobj -s %t | FileCheck %s
+# RUN: llvm-readobj -s %t | FileCheck --check-prefix=EMPTY %s
+
+# EMPTY: Section {
+# EMPTY: Index: 2
+# EMPTY: Name: .bar
+# EMPTY-NEXT: Type: SHT_PROGBITS
+# EMPTY-NEXT: Flags [
+# EMPTY-NEXT: SHF_ALLOC
+# EMPTY-NEXT: SHF_EXECINSTR
+# EMPTY-NEXT: ]
.section .foo,"ax"
.quad 0
Added: lld/trunk/test/ELF/pr36475.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/pr36475.s?rev=326137&view=auto
==============================================================================
--- lld/trunk/test/ELF/pr36475.s (added)
+++ lld/trunk/test/ELF/pr36475.s Mon Feb 26 14:32:15 2018
@@ -0,0 +1,29 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "PHDRS {" > %t.script
+# RUN: echo " ph_text PT_LOAD FLAGS (0x1 | 0x4);" >> %t.script
+# RUN: echo " ph_data PT_LOAD FLAGS (0x2 | 0x4);" >> %t.script
+# RUN: echo "}" >> %t.script
+# RUN: echo "SECTIONS {" >> %t.script
+# RUN: echo " .text : { *(.text*) } : ph_text" >> %t.script
+# RUN: echo " . = ALIGN(0x4000);" >> %t.script
+# RUN: echo " .got.plt : { BYTE(42); *(.got); } : ph_data" >> %t.script
+# RUN: echo "}" >> %t.script
+# RUN: ld.lld -T %t.script %t.o -o %t.elf
+# RUN: llvm-readobj -l -elf-output-style=GNU %t.elf | FileCheck %s
+
+# CHECK: Section to Segment mapping:
+# CHECK-NEXT: Segment Sections...
+# CHECK-NEXT: 00 .text executable
+# CHECK-NEXT: 01 .got.plt
+
+.text
+.globl _start
+.type _start, at function
+_start:
+ callq custom_func
+ ret
+
+.section executable,"ax", at progbits
+.type custom_func, at function
+custom_func:
+ ret
More information about the llvm-commits
mailing list